9.3.3. Особенности архитектуры процессоров Pentium Pro и Pentium II

Процессоры Pentium Pro и Pentium II включают в себя целый набор средств

для ускорения выполнения программ. В них происходит выполнение команд не по порядку, предсказание команд и переходов, аппаратное переименование ре­гистров.

Низкоуровневая оптимизация Выполнение команд

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

add       еах,[еЬх] ; 2гп - в декодер 0 на первом такте.

2т - пауза 1 такт, пока декодер О не

1ш - декодер 1 на втором такте.

есх,[еах]

add

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

Число микроопераций для каждой команды приведено в приложении 2, но

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

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

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

Указанное в таблице время требуется для выполнения микрооперации, а ско­рость демонстрирует, с какой частотой элемент может принимать микрооперации в собственный конвейер (1 - каждый такт, 2 - каждый второй такт). То есть, на­пример, одиночная команда FADD выполняется три такта, а три последователь­ные команды FADD - тоже за три такта.

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

Существует особая группа синхронизирующих команд, любая из которых на­чинает выполняться только после того, как завершаться все микрооперации, на­ходящиеся в процессе выполнения. К таким командам относятся привилегиро­ванные команды WRMSR, INVD, INVLPG, WBINVD, LGDT, LLDT, LIDT, LTR,

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

 

Время выполнения

Скорость

Конвейер О

Блок целочисленной арифметики

1

1

Блок команд LEA

1

1

Блок команд сдвига

1

1

Блок целочисленного умножения

4

1

Блок команд FADD

3

1

Блок команд FMUL

Б

2

Блок команд FDIV

17 для 32-битных 36 для 64-битных Б6 дляВО-битных

17 36 Б6

Блок

1

1

Блок ММХ-умножений

3

1

Конвейер 1

Блок целочисленной арифметики

1

1

Блок ММХ-арифметики

1

1

Блок ММХ-сдвигов

1

1

Конвейер 2

Блок чтения

3 при кэш-попадании

1

Конвейер З

Блок записи адреса

не меньше 3

1

Конвейер 4

Блок записи данных —-—_-.-,-.

не меньше 1

1

RSM и MOV в управляющие и отладочные регистры, а также две непривилегиро­ванные команды - IRET и CPUID. Когда, например, измеряют скорость испол­нения процедуры при помощи команды RDTSC (см. раздел 10.2), полезно выпол­нить одну из синхронизирующих команд, чтобы убедиться в том, что все измеряемые команды полностью завершились.

Кэш-память

Процессоры Pentium Pro включают в себя 8-килобайтный кэш L1 для данных и 8-килобайтный кэш L1 для кода, а процессоры Pentium II соответственно по 16 Кб, но не все кэш-промахи приводят к чтению из памяти: существует кэш второго уров­ня - L2, который маскирует промахи L1. Минимальная задержка при промахе в оба кэша составляет         тактов в зависимости от состояния цикла обновления памяти.

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

Очередь предвыборки

Очередь предвыборки считывает прямую линию кода 16-байтными выровнен­ными блоками. Это значит, что следует организовывать условные переходы так, чтобы наиболее частым исходом было бы отсутствие перехода, и что полезно вы­равнивать команды на границы слова. Кроме того, желательно располагать редко используемый код в конце процедуры, чтобы он не считывался в очередь предвы-борки впустую.

Предсказание переходов

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

На неправильно предсказанный переход затрачивается как минимум девять тактов (в среднем от 10 до 15). На правильно предсказанный невыполняющийся переход не затрачивается никаких дополнительных тактов вообще. На правильно

предсказанный выполняющийся переход затрачивается один дополнительный

такт. Именно поэтому минимальное время исполнения цикла на Pentium Pro или

Pentium II - два и, если цикл может выполняться быстрее, он должен быть развернут.

Если команда перехода не находится в буфере, система предсказания делает следующие предположения:

безусловный переход предсказывается как происходящий, и на его выполне­ние затрачивается 5-6 тактов;

условный переход назад предсказывается как происходящий, и на его выпол­нение также затрачивается 5-6 тактов; □ условный переход вперед предсказывается как непроисходящий. При этом команды, следующие за ним, предварительно загружаются и начинают полняться, вот почему не размещайте данные сразу после команды перехода.