
Встроенные микропроцессорные системы / ВстроенныеСистемы / mps7
.docЛекция 7
2.6. Узел выборки команд
В процессорах для достижения лучшей производительности при данной скорости работы используют параллелизм (возможность выполнять две или больше операций одновременно). Существует две основные формы параллелизма: параллелизм на уровне команд и параллелизм на уровне процессора. В первом случае параллелизм осуществляется в пределах отдельных команд и обеспечивает выполнение большое количество команд в секунду. Во втором случае над задачей одновременно работает несколько процессоров.
Главное препятствие высокой скорости выполнения команд является их вызов из памяти. Для решения этой проблемы используется идея конвейера. На рис.2.12. изображен конвейер из 5 стадий.
На стадии С1 вызывается команда из памяти и помещается в буфер. На стадии С2 команда декодируется. На стадии С3 определяется местоположение операндов и они вызываются из регистров или из памяти. На стадии С4 команда выполняется. На стадии С5 результат записывается в нужный регистр или память. Все стадии работают одновременно.
Предположим, что время работы на каждой стадии 2 нс. Тогда время выполнения команды 10 нс. Во время каждой стадии завершается выполнение одной команды, поэтому такой процессор выполняет 500 mips, а не 100 mips, как в обычном процессоре.
На рис.2.13 приведен конвейер с большим количеством функциональных блоков на стадии 4– это суперскалярная архитектура.
На стадии 3 действия выполняются значительно быстрее, чем на стадии 4. Если бы стадия 3 выполняла действия за 10 нс, а все функциональные блоки также за 10 нс, то на четвертой стадии всегда функционировал бы только один блок, что сделало бы эту архитектуру бессмысленной. В действительности большинство функциональных блоков четвертой стадии работают значительно дольше (блоки загрузки, сохранения и плавающей арифметики).
Конвейеры хорошо работают с линейной последовательностью команд. В действительности в последовательности команд полно команд условного и безусловного перехода. На стадии выполнения команды безусловного перехода, в конвейер поступает следующая команда. Потому часть конвейерных процессоров выполняют команду следующую за командой безусловного перехода, а только потом ветвление, хотя по логике этого не должно быть. Позицию после перехода называют отсрочкой ветвления.
С условными переходами сложнее. Во-первых, они тоже содержат отсрочки ветвления, а во-вторых стадия выборки команд узнает, откуда нужно считать команду, позже. Это может привести к простою конвейера.
Поэтому процессоры прогнозируют ветвления. Для этого, например, предполагают, что все условные переходы назад будут осуществляться, а вперед нет или наоборот.
Существует проблема, когда переход предсказан неверно. Необходимо отменить команды, которые уже выполнены, но которые не нужно было выполнять. Первый способ отмены команд – продолжить выполнять команды, вызванные после прогнозирования, до тех пор, пока одна из этих команд не попытается изменить состояние процессора (сохранение значения в регистре). Вместо перезаписи программно-доступного регистра, значение помещается в скрытый регистр, а затем, когда станет известно, что прогноз правильный, скопировать этот регистр в нужный. Второй способ отмены команды - сохранение регистров, которые вероятно будут перезаписаны, в скрытых регистрах. В случае неправильного предсказания можно будет восстановить состояние процессора.
В суперскалярной архитектуре команды могут выполняться не в том порядке в каком они выбираются из памяти. Если команде требуется значение, которое вычисляется предыдущей командой, вторая команда не может начать выполняться, пока первая не выдаст нужную величину. В такой ситуации взаимосвязанности второй команде придется ждать, что может привести к снижению производительности. Различают взаимозависимости WAR (Write After Read – запись после чтения) и WAW (Write After Write – запись после записи). В конвейерных процессорах используют механизмы изменения последовательности и подмены регистров, позволяющие завершать команды в том порядке, в котором они выбираются из памяти.
На рис.2.14. приведена реализация суперскалярной архитектуры для процессора Pentium II. Команды поступают на конвейер на стадии IFU0, куда из кэша команд загружается 32 байтная строка всякий раз, когда входной буфер пуст. Поскольку в множестве команд содержатся команды разной длины, на следующей стадии, IFU1, происходит анализ потока байтов, чтобы определить начало каждой команды (может рассматриваться до 30 команд вперед). На стадии IFU2 команды выравниваются.
Декодирование начинается на стадии ID0, т.е. преобразование каждой команды в одну (передача из регистра в регистр) или несколько микроопераций. На стадии ID0 имеется три встроенных декодера: два для простых команд и один для остальных команд. На выходе получается последовательность микроопераций. Каждая микрооперация содержит код операции, два входных и один выходной регистр.
Очередь микроопераций выстраивается на стадии ID1. Здесь же происходит прогнозирование ветвления, преодолеваются взаимозависимости WAR и WAW с использованием замены регистров на теневые и наконец, микрооперации копируются в ROB (ReOder Buffer – буфер переупорядочивания команд). Если операнды микрооперации и регистр результата доступны, а операционный блок свободен, микрооперация выполняется.
Блок отправки/выполнения устанавливает очередность и выполняет микроопераций, разрешает взаимозависимости и конфликты ресурсов. За цикл можно выпустить для выполнения пять микроопераций по одной на каждый порт. Такую скорость нельзя поддержать, поскольку она превышает способности работы блока возврата.
Блок отправки/выполнения состоит из резервации и функциональных блоков, которые связаны с пятью портами. Резервация представляет собой очередь из 20 элементов для микроопераций, которые имеют собственные операнды. Они ожидают своей очереди на выполнение в резервации, пока не освободится нужный функциональный блок. Поскольку через один порт за один цикл может выдаваться только одна микрооперация, то если двум микрооперациям нужно пройти через один и тот же порт, одной из них придется подождать.
Когда микрооперация выполнена, она переходит обратно в резервацию, а затем в ROB, и там ожидает возврата.
Блок возврата отвечает за отправку результата в нужные места – в соответствующий регистр или другие устройства блока отправки/выполнения, которым требуются данные значения. Блок отправки/выполнения содержит “официальные регистры”, т.е. те, в которых хранятся значения завершенных команд. Блок возврата содержит ряд “промежуточных регистров”, значения которых были вычислены командой, которая еще не завершилась, поскольку выполнение предыдущих команд не закончилось.
Рассматриваемая архитектура поддерживает спекулятивное выполнение (выполнение до того, как известно понадобится ли команда), поэтому некоторые команды будут выполняться напрасно, и их результаты никуда не нужно будет отправлять. Именно поэтому и нужна способность возвращаться в предыдущее состояние. Если стало известно, что какая-то микрооперация пришла из команды, которую не нужно было выполнять, результаты этой микрооперации отбрасываются. Все это контролирует блок возврата. Только результаты “официально” выполненных команд могут возвращаться в регистры, причем это должно происходить в том же порядке, что и в программе, даже если команды выполнялись в другом порядке.