2 8 8 Глава 4. Микроархитектурный уровень
А теперь вернемся к циклу 2. Мы можем разбить микрокоманду swap2 на мик-
рошаги и начать их выполнение. В цикле 2 мы копируем значение SP в регистр В,
затем пропускаем значение через АЛУ в цикле 3 и, наконец, сохраняем его в реги-
стре MAR в цикле 4. Пока все хорошо. Должно быть ясно, что если мы сможем
начинать новую микрокоманду в каждом цикле, скорость работы машины увели-
чится в три раза. Такое повышение скорости происходит за счет того, что машина
Mic-З производит в три раза больше циклов в секунду, чем Mic-2. Фактически мы
построили конвейерный процессор.
К сожалению, мы наткнулись на преграду в цикле 3. Мы бы рады начать мик-
рокоманду swap3, но эта микрокоманда сначала пропускает значение MDR через
АЛУ, а значение MDR не будет получено из памяти до начала цикла 5. Ситуация,
когда следующий микрошаг не может начаться, потому что перед этим нужно по-
лучить результат выполнения предыдущего микрошага, называется
реальной вза-
имозависимостью
или
RAW-взаимозависимостью (Read After Write — чтение
после записи).
В такой ситуации требуется считать значение регистра, которое
еще не записано. Единственное разумное решение в данном случае — отложить
начало микрокоманды swap3 до того момента, когда значение MDR станет доступ-
ным, то есть до пятого цикла. Ожидание нужного значения называется
простаива-
нием.
После этого мы можем начинать выполнение микрокоманд в каждом цикле,
поскольку таких ситуаций больше не возникает, хотя имеется пограничная ситуа-
ция: микрокоманда swap6 считывает значение регистра Н в цикле, который следует
сразу после записи этого регистра в микрокоманде swap3. Если бы значение этого
регистра считывалось в микрокоманде swap5, машине пришлось бы простаивать
один цикл.
Хотя программа Mic-З занимает больше циклов, чем программа Mic-2, она ра-
ботает гораздо быстрее. Если время цикла микроархитектуры Mic-З составляет
ДТ наносекунд, то для выполнения команды SWAP машине Mic-З требуется 11ДТ не,
а машине Mic-2 нужно 6 циклов по ЗДТ не каждый, то есть всего 18ДТ не. Конвей-
еризация увеличивает скорость работы компьютера, даже несмотря на то, что один
раз приходится простаивать из-за явления взаимозависимости.
Конвейеризация является ключевой технологией во всех современных процес-
сорах, поэтому важно хорошо понимать эту технологию. На рис. 4.22 графически
проиллюстрирована конвейеризация тракта данных, изображенного на рис. 4.21.
В первой колонке демонстрируется, что происходит во время цикла 1, вторая ко-
лонка представляет цикл 2 и т. д. (предполагается, что простаиваний нет). Закра-
шенная область на рисунке для цикла 1 и команды 1 означает, что блок выборки
команд занят вызовом команды 1. В цикле 2 значения регистров, вызванных
командой 1, загружаются в А и В, а в это время блок выборки команд занимается
вызовом команды 2. Все это также показано с помощью закрашенных серым
прямоугольников.
Во время цикла 3 команда 1 использует АЛУ
и
схему сдвига, регистры А
и
В
загружаются для команды 2, а команда 3 вызывается. Наконец, во время цикла 4
работают все 4 команды одновременно. Сохраняются результаты выполнения ко-
манды 1, АЛУ выполняет вычисления для команды 2, регистры А и В загружают-
ся для команды 3, а команда 4 вызывается.
Разработка микроархитектурного уровня
289
Блок
выборки
команд
П=
*
¥
Reg
Блок
выборки
команд
Reg
Блок
выборки
команд
1Г
4
Reg
Блок
выборки
команд
= :
|ГГ=5
Req
1
Цикл 1
Цикл 2
Цикл 3
Цикл 4
Время
Рис. 4.22. Графическое изображение работы конвейера
Если бы мы показали цикл 5 и следующие, модель была бы точно такой же, как
в цикле 4: все четыре части тракта данных работали бы независимо друг от друга.
Данный конвейер содержит 4 стадии: для вызова команд, для доступа к операн-
дам, для работы АЛУ и для записи результата обратно в регистры. Он похож на
конвейер, изображенный на рис. 2.3,
а,
только у него отсутствует стадия декодиро-
вания (расшифровки). Здесь важно подчеркнуть, что хотя выполнение одной ко-
манды занимает 4 цикла, в каждом цикле начинается новая команда и завершается
предыдущая.
Можно рассматривать схему на рис. 4.22 не вертикально (по колонкам), а гори-
зонтально (по строчкам). При выполнении команды 1 в цикле 1 функционирует
блок выборки команд. В цикле 2 значения регистров помещаются на шины А и В.
В цикле три происходит работа АЛУ и схемы сдвига. Наконец, в цикле 4 получен-
ные результаты сохраняются в регистрах. Отметим, что имеется 4 доступные части
290 Глава 4. Микроархитектурный уровень
аппаратного обеспечения, и во время каждого цикла определенная команда исполь-
зует только одну из них, оставляя свободными другие части для других команд.
Проведем аналогию с конвейером на заводе по производству машин. Чтобы
изложить основную суть работы такого конвейера, представим, что ровно каждую
минуту звучит гонг, и в этот момент все машины передвигаются по линии на один
пункт. В каждом пункте рабочие выполняют определенную операцию с машиной,
которая находится перед ними, например ставят колеса или тормоза. При каждом
ударе гонга (это 1 цикл) одна новая машина поступает на конвейер и одна собран-
ная машина сходит с конвейера. Завод выпускает одну машину в минуту незави-
симо от того, сколько времени занимает сборка одной машины. В этом и состоит
суть работы конвейера. Такой подход в равной степени применим и к процессо-
рам, и к производству машин.
Конвейер с 7 стадиями: Mic-4
Мы не упомянули о том факте, что каждая микрокоманда выбирает следующую
за ней микрокоманду. Большинство из них просто выбирают следующую команду
в текущей последовательности, но последняя из них, например swap6, часто совер-
шает межуровневый переход, который останавливает работу конвейера, посколь-
ку после этого перехода вызывать команды заранее уже становится невозможно.
Поэтому нам нужно придумать лучшую технологию.
Следующая (и последняя) микроархитектура — Mic-4. Ее основные части про-
иллюстрированы на рис. 4.23, но значительное количество деталей не показано,
чтобы сделать схему более понятной. Как и Mic-З, эта микроархитектура содер-
жит блок выборки команд, который заранее вызывает слова из памяти и сохраняет
различные значения MBR.
Блок выборки команд передает входящий поток байтов в новый компонент —
блок декодирования. Этот блок содержит внутреннее ПЗУ, которое индексирует-
ся кодом операции IJVM. Каждый элемент (ряд) блока состоит из двух частей:
длины команды IJVM и индекса в другом ПЗУ— ПЗУ микроопераций. Длина
команды IJVM нужна для того, чтобы блок декодирования мог разделить входя-
щий поток байтов и установить, какие байты являются кодами операций, а какие
операндами. Если длина текущей команды составляет 1 байт (например, длина
команды POP), то блок декодирования определяет, что следующий байт — это код
операции. Если длина текущей команды составляет 2 байта, блок декодирования
определяет, что следующий байт — это операнд, сразу за которым следует другой
код операции. Когда появляется префиксная команда WIDE, следующий байт преоб-
разуется в специальный расширенный код операции, например, WIDE+ILOAD пре-
вращается в WIDE_ILOAD.
Блок декодирования передает индекс в ПЗУ микроопераций, который он находит
в своей таблице, следующему компоненту,
блоку формирования очереди.
Этот блок
содержит логические схемы и две внутренние таблицы: одна — для ПЗУ и одна —
для ОЗУ. В ПЗУ находится микропрограмма, причем каждая команда IJVM со-
держит набор последовательных элементов, которые называются
микроопераци-
Разработка микроархитектурного уровня
291
ями.
Эти элементы должны быть расположены в строгом порядке, и, например,
переход из wide_iload2 в iload2, который допустим в микроархитектуре Mic-2, не
разрешается. Каждая последовательность микроопераций должна выполняться
полностью, в некоторых случаях последовательности дублируются.
Длина
команды ILVM
©
Из памяти
7
Блок
декодирования
Индекс
микрооперации
I
Бит завершения
Бит перехода
Блок формирования
,
л
.
ОЗУ микроопераций
очереди
IADD
ISUB
ILOAD
IFLT
Очередь
незаконченных
микроопераций
Стадия передачи 4 |АЛУ| С | М JA| В
Стадия передачи 5
Стадия передачи 6
С |М|А|В|
Стадия передачи 7 |АЛУ| С |М|А|В|
MIR1
MIR2
MIR3
MIR4
Рис. 4.23.
Основные компоненты микроархитектуры Mic-4
Структура микрооперации сходна со структурой микрокоманды (см. рис. 4.4),
только в данном случае поля NEXT_ADDRESS и JAM отсутствуют и требуется
новое поле для определения входа на шину А. Имеется также два новых бита: бит
завершения (Final bit) и бит перехода (Goto bit). Бит завершения устанавливается
на последней микрооперации каждой последовательности (чтобы обозначить эту
операцию). Бит перехода нужен для указания на микрооперации, которые явля-
ются условными микропереходами. По формату они отличаются от обычных мик-
роопераций. Они состоят из битов JAM и индекса в ПЗУ микроопераций. Микро-
команды, которые раньше осуществляли какие-либо действия с трактом данных, а
также выполняли условные микропереходы (например, iflt4), теперь нужно раз-
бивать на две микрооперации.
292 Глава 4. Микроархитектурный уровень
Блок формирования очереди работает следующим образом. Он получает от
блока декодирования индекс микрооперации ПЗУ. Затем он отыскивает микро-
операцию и копирует ее во внутреннюю очередь. Затем он копирует следующую
микрооперацию в ту же очередь, а также следующую за этой микрооперацией. Так
продолжается до тех пор, пока не появится микрооперация с битом завершения.
Тогда блок копирует эту последнюю микрооперацию и останавливается. Если блоку
не встретилась микрооперация с битом перехода и у него осталось достаточно сво-
бодного пространства, он посылает сигнал подтверждения приема блоку декоди-
рования. Когда блок декодирования воспринимает сигнал подтверждения, он по-
сылает блоку формирования очереди следующую команду IJVM.
Таким образом, последовательность команд IJVM в памяти в конечном итоге
превращается в последовательность микроопераций в очереди. Эти микрооперации
передаются в регистры MIR, которые посылают сигналы тракту данных. Но есть
еще один фактор, который нам нужно рассмотреть: поля каждой микрооперации
не действуют одновременно. Поля А и В активны во время первого цикла, поле
АЛУ активно во время второго цикла, поле С активно во время третьего цикла,
а все операции с памятью происходят в четвертом цикле.
Чтобы все эти операции выполнялись правильно, мы ввели 4 независимых ре-
гистра MIR в схему на рис. 4.23. В начале каждого цикла (на рис. 4.2 это время
Aw)
значение MIR3 копируется в регистр MIR4, значение MIR2 копируется в регистр
MIR3, значение MIR1 копируется в регистр MIR2, а в MIR1 загружается новая
микрооперация из очереди. Затем каждый регистр MIR выдает сигналы управле-
ния, но используются только некоторые из них. Поля А и В из регистра MIR1
применяются для выбора регистров, которые запускают защелки А и В, а поле АЛУ
в регистре MIR1 не используется и не связано ни с чем на тракте данных.
В следующем цикле микрооперация передается в регистр MIR2, а выбранные
регистры в данный момент находятся в защелках А и В. Поле АЛУ теперь исполь-
зуется для запуска АЛУ. В следующем цикле поле С запишет результаты обратно
в регистры. После этого микрооперация передается в регистр MIR4 и инициирует
любую необходимую операцию памяти, используя загруженное значение регист-
ра MAR (или MDR для записи).
Нужно обсудить еще один аспект микроархитектуры Mic-4: микропереходы.
Некоторым командам IJVM нужен условный переход, который осуществляется
с помощью бита N. Когда происходит такой переход, конвейер не может продол-
жать работу. Именно поэтому нам пришлось добавить в микрооперацию бит пе-
рехода. Когда в блок формирования очереди поступает микрооперация с таким
битом, блок воздерживается от передачи сигнала о получении данных блоку деко-
дирования. В результате машина будет простаивать до тех пор, пока этот переход
не разрешится.
Предположительно, некоторые команды IJVM, не зависящие от этого перехо-
да, уже переданы в блок декодирования, но не в блок формирования очереди, по-
скольку он еще не выдал сигнал о получении. Чтобы разобраться в этой путанице
и вернуться к нормальной работе, требуется специальное аппаратное обеспечение
и особые механизмы, но мы не будем рассматривать их в этой книге. Э. Дейкстра,
написавший знаменитую работу «GOTO Statement Considered Harmful» («Выра-
жение GOTO губительное), был прав.