Assembler - язык неограниченных возможностей

         

Выполнение команд


Процессор Pentium содержит два конвейера исполнения целочисленных команд (U и V) и один конвейер для команд FPU. Он может выполнять две целочисленные команды одновременно и поддерживает механизм предсказания переходов, значительно сокращающий частоту сброса очереди предвыборки из-за передачи управления по другому адресу.

Процессор перед выполнением команды анализирует сразу две следующие команды, находящиеся в очереди и, если возможно, выполняет одну из них в U-конвейере, а другую в V. Если это невозможно, первая команда загружается в U-конвейер, а V-конвейер пустует.

V-конвейер имеет определенные ограничения на виды команд, которые могут в нем исполняться. Приложение 2 содержит для каждой команды информацию о том, может ли она выполняться одновременно с другими командами и в каком конвейере. Кроме того, две команды не будут запущены одновременно, если:

  • команды подвержены одной из следующих регистровых зависимостей:
    1. Первая команда пишет в регистр, а вторая читает из него.
    2. Обе команды пишут в один и тот же регистр (кроме записи в EFLAGS).
    3. Исключения из этих правил— пары PUSH/PUSH, PUSH/POP и PUSH/CALL, выполняющие запись в регистр ESP;

    4. одна из команд не находится в кэше команд (кроме случая, если первая команда — однобайтная);
    5. одна из команд длиннее семи байт (для Pentium);
    6. одна команда длиннее восьми байт, а другая — семи (для Pentium ММХ).
    7. Помните, что простыми перестановками команд можно выиграть до 200% скорости в критических ситуациях.

      Каждый такт процессора до трех команд может быть прочитан и декодирован на микрооперации из очереди предвыборки. В этот момент работают три декодера, первый из которых может декодировать команды, содержащие до четырех микроопераций, а другие два— только команды из одной микрооперации. Если в ассемблерной программе команды упорядочены в соответствии с этим правилом (4–1–1), то все время на каждый такт будет происходить декодирование трех команд, например, если в последовательности команд

      add eax,[ebx] ; 2m - в декодер 0 на первом такте mov есх,[еах] ; 2m - пауза 1 такт, пока декодер 0 ; не освободится add edx,8 ; 1m - декодер 1 на втором такте

      переставить вторую и третью команды, команда add edx,8 будет декодирована в тот же такт, что и первая команда.

      Число микроопераций для каждой команды приведено в приложении 2, но можно сказать, что команды, работающие только с регистрами, как правило, выполняются за одну микрооперацию, команды чтения из памяти — тоже за одну, команды записи в память — за две, а команды, выполняющие чтение-изменение-запись, — за четыре. Сложные команды содержат больше четырех микроопераций и требуют несколько тактов для декодирования. Кроме того, команды длиннее семи байт не могут быть декодированы за один такт. В среднем время ожидания в этом буфере составляет около трех тактов.

      Затем микрооперации поступают в буфер накопления, где они ждут, пока все необходимые им данные не будут доступны. Затем они посылаются в ядро системы неупорядоченного исполнения, состоящей из пяти конвейеров, каждый из которых обслуживает несколько блоков исполнения. Если все данные для микрооперации готовы и в ядре есть свободный элемент, исполняющий данную микрооперацию, в буфере накопления не будет потрачено ни одного лишнего такта. После выполнения микрооперации скапливаются в буфере завершения, где результаты их записываются, операции записи в память упорядочиваются и микрооперации завершаются (три за один такт).


      Время выполнения команд в пяти конвейерах исполнения приведено в таблице 21.

      Таблица 21. Конвейеры процессора Pentium Pro/Pentium II

        Время выполнения Скорость
      Конвейер 0
      Блок целочисленной арифметики 1 1
      Блок команд LEA 1 1
      Блок команд сдвига 1 1
      Блок целочисленного умножения 4 1
      Блок команд FADD 3 1
      Блок команд FMUL 5 2
      Блок команд FDIV 17 для 32-битных
      36 для 64-битных
      56 для 80-битных
      17
      36
      56
      Блок MMX-арифметики 1 1
      Блок MMX-умножений 3 1
      Конвейер 1
      Блок целочисленной арифметики 1 1
      Блок MMX-арифметики 1 1
      Блок MMX-сдвигов 1 1
      Конвейер 2
      Блок чтения 3 при кэш-попадании 1
      Конвейер 3
      Блок записи адреса не меньше 3 1
      Конвейер 4
      Блок записи данных не меньше 1 1
      Указанное в таблице время — это время, требующееся для выполнения микрооперации, а скорость — с какой частотой элемент может принимать микрооперации в собственный конвейер (1 — каждый такт, 2 — каждый второй такт). То есть, например, одиночная команда FADD выполняется за три такта, но три последовательные команды FADD выполнятся также за 3 такта.

      Микрооперации чтения и записи, обращающиеся к одному и тому же адресу в памяти, выполняются за один такт.

      Существует особая группа синхронизирующих команд, любая из которых начинает выполняться только после того, как завершатся все микрооперации, находящиеся в состоянии выполнения. К таким командам относятся привилегированные команды WRMSR, INVD, INVLPG, WBINVD, LGDT, LLDT, LIDT, LTR, RSM и MOV в управляющие и отладочные регистры, а также две непривилегированные команды — IRET и CPUID. В тех случаях, когда, например, измеряют скорость выполнения процедуры при помощи команды RDTSC (глава 10.2), полезно выполнить одну из синхронизирующих команд, чтобы убедиться, что все измеряемые команды полностью завершились.


      Содержание раздела