Помещение основного цикла в конце каждой последовательности микрокоманд.
3-шинная архитектура
Что еще можно сделать, чтобы сократить длину пути? Можно подвести к АЛУ две полные входные шины, А и В, и, следовательно, всего получится три шины. Все (или по крайней мере большинство регистров) должны иметь доступ к обеим входным шинам. Преимущество такой системы состоит в возможности складывать любой регистр с любым другим регистром за один цикл. Чтобы увидеть, насколько продуктивен такой подход, рассмотрим реализацию команды IL0AD (табл. 4.6).
Таблица 4.6. Микропрограмма для выполнения команды ILOAD |
||
Микрокоманда |
Операции |
Комментарий |
iloadl |
Н = LV |
MBR содержит индекс; копирование LV в Н |
iload2 |
MAR = MBRU + H; rd |
MAR = адрес локальной переменной, которую нужно поместить в стек |
iload3 |
MAR = SP = SP + 1 |
Регистр SP указывает на новую вершину стека; подготовка к записи |
iload4 |
PC = PC + 1; fetch; wr |
Увеличение PC на 1; вызов следующего кода операции; запись вершины стека |
iloadö |
TOS = MDR; goto Maini |
Обновление TOS |
Maini |
PC = PC+ 1; fetch; goto(MBR) |
Регистр MBR содержит код операции; вызов следующего байта; переход |
Мы видим, что в микрокоманде iloadl значение LV копируется в регистр Н. Это нужно только для того, чтобы сложить Н с MBRU в микрокоманде iload2. В разработке с двумя шинами нет возможности складывать два произвольных регистра, поэтому один из них сначала нужно скопировать в регистр Н. В 3-шин-ной архитектуре мы можем сэкономить один цикл, как показано в табл. 4.7. Мы добавили основной цикл к команде IL0AD, но при этом длина пути не увеличилась и не уменьшилась. Однако дополнительная шина сокращает общее время выполнения команды с шести циклов до пяти. Теперь мы знаем вторую возможность сокращения длины пути:
Переход от 2-шинной к 3-шинной архитектуре.
Таблица 4.7. Микропрограмма для выполнения команды ILOAD в 3-шинной архитектуре
Микрокоманда |
Операции |
Комментарий |
|
Iloadl |
MAR |
= MBRU + LV; rd |
MAR = адрес локальной переменной, которую нужно поместить в стек |
Hoad2 |
MAR |
= SP = SP + 1 |
Регистр SP указывает на новую вершину стека; подготовка к записи |
Hoad3 |
PC - |
PC + 1; fetch; wr |
Увеличение PC на 1; вызов следующего кода операции; запись вершины стека |
Hoad4 |
TOS |
= MDR |
Обновление TOS |
Hoad5 |
PC = |
PC + 1; fetch; goto(MBR) |
Регистр MBR уже содержит код операции; вызов индексного байта |
Блок выборки команд
Обе описанные возможности вполне привлекательны, но чтобы достичь существенного продвижения, требуется нечто более радикальное. Давайте вернемся чуть-чуть назад и рассмотрим обычные составляющие любой команды: поля вызова и декодирования. Отметим, что в каждой команде могут происходить следующие операции:
♦ значение РС пропускается через АЛУ и увеличивается на 1;
♦ РС используется для вызова следующего байта в потоке команд;
♦ операнды считываются из памяти;
♦ операнды записываются в память;
♦ АЛУ выполняет вычисление, и результаты сохраняются в памяти.
Если команда содержит дополнительные поля (для операндов), каждое поле должно вызываться явно, по одному байту за раз. Поле можно использовать только после того, как эти байты будут объединены. При вызове и компоновке поля АЛУ должно для каждого байта увеличивать РС на единицу, а затем объединять получившийся индекс или смещение. Когда, помимо выполнения основной работы команды, приходится вызывать и объединять поля этой команды, АЛУ используется практически в каждом цикле.