ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 24.12.2021

Просмотров: 12183

Скачиваний: 10

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

Увеличение производительности 313

чтобы выполнение этих команд началось раньше, а полученные результаты были
бы доступны в тот момент, когда они понадобятся. Естественно, при каждой ите-
рации требуется только одно значение, поэтому остальные команды LOAD будут от-
брасываться, но если кэш-память и основная память конвейеризированы, то по-

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

понадобится ли вообще эта команда, называется

 спекулятивным выполнением.

Чтобы использовать эту технологию, требуется поддержка компилятора, аппарат-

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

должен перемещать команды явным образом.

В связи со спекулятивным выполнением команд возникают некоторые инте-

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

манд не имела окончательного результата, который нельзя отменить, поскольку

позднее может оказаться, что эти команды не нужно было выполнять Обратимся
к листингу 4.6 и рис. 4 30. Очень удобно производить сложение, как только появ-

ляется значение

 к

 (даже до условною оператора if), но нежелательно сохранять

результаты в памяти. Чтобы предотвратить перезапись регистров до того, как ста-
ло известно, полезны ли полученные результаты, нужно переименовать (подме-
нить) все выходные регистры, которые используются спекулятивной командой.

Как вы можете себе представить, счетчик обращений для отслеживания всего это-

го очень сложен, но при наличии соответствующего аппаратного обеспечения его
вполне можно сделать.

Однако при наличии спекулятивных команд возникает еще одна проблема, ко-

торую нельзя решить путем подмены регистров А что происходит, если спекуля-
тивная команда вызывает исключение (exception)? В качестве примера можно

привести команду LOAD, которая вызывает промах кэш-памяти в компьютере с до-

статочно большим размером строки кэш-памяти (скажем, 256 байт) и памятью,

которая работает гораздо медленнее, чем центральный процессор и кэш. Если нам
требуется команда

 LOAD

 и работа машины останавливается на много циклов, на то

время, пока загружается строка кэш-памяти, то это не так страшно, поскольку

данное слово действительно нужно Но если машина простаивает, чтобы вызвать

слово, которое, как окажется позднее, совершенно ни к чему, это совершенно не

рационально. Если подобных «оптимизаций» слишком много, то центральный про-

цессор будет работать медленнее, чем если бы этих «оптимизаций» вообще не было.
(Если машина содержит виртуальную память, которая обсуждается в главе 6, то
спекулятивное выполнение команды LOAD может даже вызвать обращение к отсут-

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

В ряде современных компьютеров данная проблема решается следующим об-

разом. В них содержится специальная команда SPECULATIVE-LOAD, которая произво-

дит попытку вызвать слово из кэш-памяти, а если слова там нет, просто прекраща-

ет вызов. Если значение находится там и если в данный момент оно действительно
требуется, его можно использовать, но если оно в данный момент не требуется,
аппаратное обеспечение должно сразу получить это значение. А если окажется,

что данное значение нам не нужно, то никаких потерь не будет.


background image

314 Глава 4. Микроархитектурный уровень

Более сложную ситуацию можно проиллюстрировать следующим выражением:

if (x>0)

 z-y/x;

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

(эта команда выполняется медленно) перемещается вверх и выполняется еще

до условного оператора i f. К сожалению, если х равен 0, то программа завершается

в результате попытки деления на 0. Таким образом, спекулятивная команда при-
водит к сбою в изначально правильной программе. Еще хуже то, что программист

изменяет программу, чтобы предотвратить подобную ситуацию, но сбой все равно
происходит.

Одно из возможных решений — специальные версии команд, которые могут

вызвать исключения (exceptions). Кроме того, к каждому регистру добавляется
специальный бит

 (poison bit).

 Если спекулятивная команда дает сбой, она не вы-

зывает trap (ловушку), а устанавливает бит присутствия в регистр результатов.

Если этот регистр позднее используется обычной командой, происходит trap (как

и должно быть). Однако если этот результат не используется, бит присутствия сбра-
сывается и не причиняет программе никакого вреда.

Примеры микроархитектурного уровня

В этом разделе мы рассмотрим три современных процессора в свете понятий, изу-

ченных в этой главе. Наше изложение будет кратким, поскольку компьютеры чрез-

вычайно сложны, содержат миллионы вентилей и у нас нет возможности давать

подробное описание. Примеры будут те же, которые мы использовали до сих пор;

Pentium II, UltraSPARC II и picojava П.

Микроархитектура процессора Pentium II

Pentium II — один из процессоров семейства Intel. Он поддерживает 32-битные

операнды и арифметику, 64-битные операции с плавающей точкой, а также 8- и

16-битные операнды и операции, которые унаследованы от предыдущих процес-

соров данного семейства. Процессор может адресовать до 64 Гбайт памяти и счи-
тывать слова из памяти по 64 бита за раз. Обычная система Pentium II изображена

на рис. 3.47.

Как мы уже говорили раньше и как показано на рис. 3.40, картридж с одноряд-

ным расположением контактов (SEC) системы Pentium II состоит из двух интег-
ральных схем: центрального процессора (на котором находится разделенная кэш-

память первого уровня) и объединенной кэш-памяти второго уровня. На рис. 4.31
показаны основные компоненты центрального процессора: блок вызова/декоди-

рования, блок отправки/выполнения и блок возврата, которые вместе действу-

ют как конвейер высокого уровня. Эти три блока обмениваются данными через
пул команд — место для хранения информации о частично выполненных коман-

дах. Информация в пуле команд находится в таблице, которая называется

 ROB

(ReOrder Buffer

 —

 буфер переупорядочивания команд).

 Если излагать кратко,


background image

Примеры микроархитектурного уровня

315

блок вызова/декодирования вызывает команды и разбивает их на микрооперации

для хранения в ROB. Блок отправки выполнения получает микрооперации из буфе-

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

Связь с кэш-памятью

второго уровня

\7

Локальная шина,

связанная с мостом PCI

\7

Устройство сопряжения с шиной

Кэш-память первого

уровня для команд

Кэш-память первого

уровня для данных

1

Блок вызова

декодирования

Блок отправки

выполнения

Блок возврата

Задатчик

последовательности

микроопераций

Рис. 4 . 3 1 . Микроархитектура Pentium И

Блок сопряжения с шиной отвечает за обмен информацией с системой памяти

(и с кэш-памятью второго уровня, и с основной памятью). Кэш-память второго

уровня не связана с локальной шиной, поэтому блок сопряжения с шиной отвеча-

ет за вызов данных из основной памяти через локальную шину, а также за загрузку

всех блоков кэш-памяти. Система Pentium II использует протокол синхронизации
кэш-памяти MESI, который мы будем рассматривать, когда дойдем до мультипро-
цессоров в разделе «Архитектуры UMA SMP с шинной организацией» главы 8.

Блок вызова/декодирования

Блок вызова/декодирования отличается высокой степенью конвейеризации (со-

держит семь стадий). На рис. 4.32 эти семь стадий обозначены IFU0,..., ROB.

Блок отправки/выполнения и блок возврата имеют еще пять стадий, то есть всего

стадий 12. Команды поступают на конвейер на стадии IFUO (IFU — аббревиатура

от Instruction Fetch Unit — блок выборки команд), куда из кэша команд загружа-

ются целые 32-байтные строки. Всякий раз, когда внутренний буфер пуст, туда

копируется следующая строка кэш-памяти. Регистр NEXT IP (NEXT Instruction
Pointer — следующий указатель команды) управляет процессом вызова команд.


background image

316

Глава 4. Микроархитектурный уровень

Кэш-память первого

уровня для команд

Стадия конвейера

IFU0

IFU1

IFU2

ID0

RAT

Блок выборки строк

кэш-памяти

Декодер длины команд

Блок выравнивания команд

m пи  : ^

Блок формирования

очереди микрооперации

Распределитель регистров

Next IP

Устройство динамического

прогнозирования ветвления

Задатчик

поел едовател ьности

микроопераций

Устройство статического

прогнозирования ветвления

ROB

Микрооперации поступают

в регистр ROB

Рис. 4.32.

 Внутренняя структура блока вызова/декодирования (в упрощенном виде)

Поскольку в наборе команд Intel, который часто называют IA-32 (32-разряд-

ная архитектура для процессоров Intel), содержатся команды разной длины и раз-

личного формата, на следующей стадии, IFU1, происходит анализ потока байтов,

чтобы определить начало каждой команды. В случае необходимости на стадии IFU1
может рассматриваться до 30 команд архитектуры IA-32 вперед. К сожалению,
вследствие этого обычно встречаются 4 или 5 условных переходов, не все из кото-
рых правильно прогнозируются, поэтому в обработке такого большого количества

команд заранее нет особого смысла. На стадии IFU2 команды выравниваются, по-

этому в следующей стадии они без труда декодируются.

Декодирование начинается на стадии Ш0 (Instruction Decoding — декодирова-

ние команды). Декодирование в системе Pentium II состоит из превращения каж-

дой команды IA-32 в одну или несколько микроопераций, как и в микроархитек-

туре Mic-4. Простые команды, например перемещение из одного регистра в другой,
переделываются в одну микрооперацию. Выполнение более сложных команд мо-
жет занимать до четырех микроопераций. Несколько чрезвычайно сложных ко-
манд требуют еще больше микроопераций и используют ПЗУ последовательнос-
ти микроопераций для упорядочения этих микроопераций.

На стадии ID0 имеется три внутренних декодера. Два из них предназначены

для простых команд, а третий обрабатывает остальные команды. На выходе полу-

чается последовательность микроопераций. Каждая микрооперация содержит код
операции, два входных и один выходной регистр.

Очередь микрокоманд выстраивается на стадии ID1. Этот блок аналогичен бло-

ку формирования очереди, изображенному на рис. 4.23. На этой стадии также про-


background image

Примеры микроархитектурного уровня 317

исходит прогнозирование ветвления (сначала статическое, на всякий случай).
Прогноз зависит от нескольких факторов, но для переходов, связанных с текущей
командой, считается, что переходы назад будут производиться, а переходы впе-

ред — нет Затем идет динамическое прогнозирование с использованием специ-
ального алгоритма, как показано на рис. 4 29, только в данном случае для прогно-
зирования используется не два, а четыре бита. Должно быть ясно, что если речь
идет о конвейере с 12 стадиями, очень велика вероятность неправильного пред-

сказания, и поэтому нужно так много битов. Если перехода в таблице динамики

нет, используется статическое прогнозирование.

Чтобы избежать взаимозависимостей WAR и WAW, система Pentium II под-

держивает переименования (подмены), как мы видели в табл. 4.13. Реальные реги-

стры в командах IA-32 могут быть заменены в микрооперациях любым из 40 внут-

ренних временных регистров, находящихся в буфере ROB. Подмена происходит

на стадии RAT.

И наконец, микрооперации копируются в буфер ROB со скоростью три мик-

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

Если операнды микрооперации и регистр результатов доступны, а операционный

блок свободен, микрооперацию можно выпустить. В противном случае она нахо-

дится в буфере ROB, пока не появятся все необходимые ресурсы.

Блок отправки/выполнения

Перейдем к блоку отправки/выполнения, который изображен па рис. 4.33. Этот
блок устанавливает очередность и выполняет микрооперации, разрешает взаимо-

зависимости и конфликты ресурсов. Хотя за один цикл можно декодировать всего

три команды (на стадии ID0), за один цикл можно выпустить для выполнения це-

лых пять микроопераций, по одной на каждый порт. Такую скорость нельзя под-
держивать, поскольку она превышает способности работы блока возврата. Микро-

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

готова для выполнения, она может начаться, даже если другие операции, которые
поступили в буфер ROB раньше нее, еще не готовы, Если несколько микроопера-
ций пригодны для выполнения одним и тем же функциональным блоком, с помо-

щью сложного алгоритма выбирается важнейшая из них, и именно она и запуска-

ется следующей Например, выполнение перехода гораздо важнее, чем выполнение
арифметического действия, поскольку первый из них влияет на ход программы.

Блок отправки/выполнения состоит из резервации и функциональных бло-

ков, которые связаны с пятью портами Резервация представляет собой очередь из
20 элементов для микроопераций, которые имеют собственные операнды. Они ожида-

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

Между резервацией и функциональными блоками имеется пять портов. Неко-

торые функциональные блоки разделяют один порт, как показано на рисунке. Блок
загрузки и блоки запоминающих устройств выдают информацию для операций
загрузки и сохранения соответственно Для запоминающих устройств есть два пор-

та. Поскольку через один порт за один цикл может выдаваться только одна микро-
операция, то если двум микрооперациям нужно пройти через один и тот же порт,
одной из них придется подождать.