Э. Таненбаум - Архитектура компьютера (1127755), страница 87
Текст из файла (страница 87)
Следовательно, нужно сделать так, чтобы механизм переупорядочения последовательности команд можно было применять не только в пределах конкретного базового блока. Полезнее всего будет передвинуть потенциально медленную операцию в графе повыше, чтобы ее выполнение началось раньше. Это может быть команда 1.0А0, операция с плавающей точкой или даже начало длинной цепочки зависимостей. Перемещение кода вверх по ребру графа называется подъемом. Посмотрите еще раз на рис. 4.30. Представим, что все переменные, кроме ечепева и оббзвв, были помещены в регистры. Тогда имело бы смысл переместить 350 Глава 4.
Уровень микроархитектуры команды ЖОАО в начало цикла до вычисления переменной ~, чтобы выполнение этих команд началось раньше, а полученные результаты были доступны в момент, когда они понадобятся. Естественно, при каждой итерации требуется только одно значение, поэтому остальные команды ЕОАО будут отбрасываться, но если кэш-память и основная память конвейеризированы, то подобная процедура имеет смысл. Выполнение команды раньше того, как станет известно, понадобится эта команда или нет, называется спекулятивным исполнением.
Чтобы использовать эту технологию, требуется поддержка компилятора, аппаратного обеспечения, а также некоторое усовершенствование архитектуры. В большинстве случаев переупорядочение команд за пределами одного базового блока находится вне возможностей аппаратного обеспечения, поэтому компилятор должен перемещать команды явным образом. В связи со спекулятивным исполнением команд возникают некоторые интересные проблемы.
Например, очень важно, чтобы ни одна из спекулятивных команд не давала результата, который невозможно отменить, поскольку позднее может оказаться, что эту команду не нужно было выполнять. Обратимся к листингу 4.6 и рис. 4.30. Очень удобно производить сложение, как только появляется значение 1 (даже до условного оператора 1Г), но при этом нежелательно сохранять результаты в памяти. Чтобы предотвратить перезапись регистров до того, как станет известно, нужны ли полученные результаты, нужно подменить все выходные регистры, которые используются спекулятивной командой. Как вы можете себе представить, счетчик обра|цений для отслеживания всех этих ситуаций очень сложен, но при наличии соответствующего аппаратного обеспечения его вполне можно создать.
Однако при наличии спекулятивных команд возникает еще одна проблема, которую нельзя решить путем подмены регистров. Что произойдет, если спекулятивная команда вызовет исключение? В качестве примера можно привести команду ЕОАО, которая вызывает кэш-промах в компьютере со строкой кэша достаточно большого размера (скажем, 256 байт) и памятью, которая работает гораздо медленнее, чем центральный процессор и кэш.
Если нам требуется команда 1.ОАО и работа машины останавливается на несколько циклов, пока загружается строка каша, то это не так страшно, поскольку данное слово действительно нужно. Но если машина простаивает, чтобы вызвать слово, которое, как окажется позднее, нам ни к чему, это совершенно нерационально. Если подобных «оптимизаций» слишком много, то центральный процессор будет работать медленнее, чем если бы «оптимизаций» вообще не было.
(Если машина содержит виртуальную память, о которой рассказывается в главе 6, то спекулятивное выполнение команды ЖОАО может даже вызвать обращение к отсутствующей странице. Подобные ошибки могут значительно повлиять на производительность, поэтому важно их избегать.) В ряде современных компьютеров данная проблема решается следующим образом. В них поддерживается специальная команда 5РЕСОЕАТ1НЕ-ЕОАО, которая производит попытку вызвать слово из кэш-памяти, а если слова там нет, просто прекращает вызов. Если значение в кэше обнаруживается и оно действительно требуется, его можно использовать, а если его в кэше нет, аппаратное обеспечение должно сразу же его получить. Если затем окажется, что данное значение нам не нужно, то никаких потерь времени не будет.
Примеры уровня микроархитектуры 351 Более сложную ситуацию можно проиллюстрировать следующим оператором; 11 1х > 0) г = у)х; Здесь х, у и г — переменные с плавающей точкой. Предположим, что все эти переменные поступают в регистры заранее, а команда деления с плавающей точкой (эта команда выполняется медленно) перемещается вверх по графу и выполняется еще до условного оператора 1~.
К сожалению, если значение х равно О, то программа завершается в результате попытки деления на О. Таким образом, спекулятивная команда приводит к сбою в изначально правильной программе. Еще хуже то, что программист изменяет программу, чтобы предотвратить подобную ситуацию, но сбой все равно происходит.
Одно из возможных решений — специальные версии тех команд, которые могут вызывать исключения. Кроме того, к каждому регистру добавляется так называемый бит отравления (ро(зоп Ьй). Если спекулятивная команда дает сбой, она не инициирует перехват исключения, а устанавливает бит отравления в регистр результатов.
Если затем этот регистр используется обычной командой, выполняется перехват исключения (как и должно быть в случае исключения). Однако если этот результат не используется, бит отравления сбрасывается и никак не влияет на ход выполнения программы. Примеры уровня микроархитектуры В этом разделе в свете материала, изучаемого в этой главе, мы рассмотрим три современных процессора. Наше изложение будет кратким, поскольку компьютеры чрезвычайно сложны, содержат миллионы вентилей и у нас нет возможности давать подробное описание. Процессоры, предлагаемые в качестве примеров, те же, что и раньше, — Репгшш 4, Л)таЯРАКС П1 и 805 Е Микроархитектура процессора Репбит 4 На первый взгляд Репйшп 4 кажется вполне традиционной С18С-машиной с большим и громоздким набором команд, поддерживающим 8-, 16- и 32-разрядные целочисленные операции, а также 32- и 64-разрядные операции с плавающей точкой.
В нем всего 8 доступных регистров, причем ни один из них не повторяет другие. Допустимая длина команд составляет 1 — 17 байт. В об|цем, налицо стандартная унаследованная архитектура, которая все делает не так. На самом же деле процессор Репт1шп 4 основан на современном надежном В18С-ядре с развитой конвейеризацией. Его тактовая частота уже очень высока, а в последующие годы, скорее всего, вырастет еще болыпе. Удивительно, как инженерам 1пге1 на основе архаичной архитектуры удалось построить процессор, отвечающий всем современным требованиям. Итак, в этом подразделе мы рассмотрим микроархитектуру Репггцш 4 и разберемся в принципах ее работы.
352 Глава 4. Уровень микроархитектуры Обзор микроархитектуры йеФВигв1 Микроархитектура Репсшш 4, называемая 1Ь1еСВнгзФ, ознаменовала собой решительный отход от принципов микроархитектуры Рб, использовавшейся в процессорах Репошп Рго, Репгшш и и Репошп П1. Она дает определенное представление о том, на какой базе продукция 1пге1 будет разрабатываться в течение нескольких ближайших лет. Примерная схема микроархитектуры Репгшш 4 изображена на рис. 4.31.
В определенной степени она соответствует рисунку 1.8. К шине памяти Блок исполнения Подсистема памяти Системный интерфейс Блоки исполнения целочисленных операций и операций с плавающей точкой Планировщики Блок микрокоманд пересортировки декодирования Блок прогнозирования Блок предварительной обработки Контроль исполнения с изменением последовательности Рис. 4.31.
Микроархитектура реп1шгп 4 Репгшш 4 состоит из четырех основных блоков: подсистемы памяти, блока предварительной обработки, блока контроля исполнения с изменением последовательности и блока исполнения. Рассмотрим эти блоки по порядку, начиная с верхнего левого и продвигаясь против часовой стрелки. В состав подсистемы памяти входит объединенный кэш второго уровня (1.2), а также логика доступа к внешнему ОЗУ по шине памяти. В первом поколении Репишп 4 объем Е2 составлял 256 Кбайт; во втором — 512 Кбайт; в третьем— 1 Мбайт. 1.2 представляет собой 8-входовую ассоциативную кэш-память с 128- байтным строками. Если запрос к кашу второго уровня не приносит результата, организуются две 64-байтных передачи в основную память, после чего из нее выбираются необходимые блоки.
Данный кэш Е2 относится к категории кэшей Примеры уровня микроархитектуры 353 с отложенной записью. Иными словами, новые данные в измененной строке записываются обратно в память лишь после сброса. С кэшем тесно связан блок предварительной выборки (он не показан на рисунке), который пытается перенести данные из основной памяти в 1.2 еще до того, как эти данные запрошены. Из 1.2 данные могут на высокой скорости передаваться в другие блоки кэш-памяти. За один цикл может быть выполнена одна операция выборки из 1.2; так, на тактовой частоте 3 ГГц из Е2 в другие кэши теоретически можно передать до 1,5 млрд 64-байтных блоков в секунду — таким образом, пропускная способность становится равной 96 Гбайт/с.
Под изображенной на рис. 4.31 подсистемой памяти находится блок предварительной обработки, который выбирает команды из 1.2 и декодирует их в порядке выполнения команд программы. Каждая команда на уровне 1ЯА разбивается на последовательность В1БС-подобных микроопераций. Для упрощения команд блок выборки-декодирования определяет, какие микрооперации необходимы для решения внутренних задач. В более сложных случаях производится поиск последовательности микроопераций в памяти микрокоманд.