Рис. 1.19. Разрешение конфликтов в конвейере при помощи приостановок
Для приостановки стадий Fetch и Decode нужно добавить вход разрешения работы (EN) временным регистрам, расположенным перед этими стадиями, а также вход синхронного сброса (CLR) временному регистру, расположенному перед стадией Execute.
Когда возникает необходимость приостановить конвейер из-за команды lw,устанавливаются сигналы StallD и StallF, запрещающие временным регистрам перед стадиями Decode и Fetch изменять их старое значение. Также устанавливается сигнал FlushE, очищающий содержимое временного регистра перед стадией Execute, что приводит к появлении юпузырька.
Для команды lw всегда устанавливается сигнал MemtoReg. Таким образом, логика формирования сигналов приостановки (stall) и очистки (flush) выглядит так:
lwstall = ((rsD = = rtE) OR (rtD = = rtE)) AND MemtoRegEStallF = StallD = FlushE = lwstall
46
Разрешение конфликтов управления
Выполнение команды beq приводит к конфликту управления: конвейерный процессор не знает, какую команду выбрать следующей, поскольку в этот момент еще не ясно, нужно ли будет выполнить условный переход или нет.
Один из способов разрешить этот конфликт – приостановить конвейер до тех пор, пока не будет принято нужное решение (т.е. до тех пор, пока не будет вычислен сигнал PCSrc). Решение принимается в стадии Memory, так что для каждой команды условного перехода придется приостанавливать конвейер на три такта. Такое решение повлекло бы весьма плачевные последствия для производительности системы.
Есть и альтернативный способ – предсказать, будет ли выполнен условный переход или нет, и начать выполнять команды, основываясь на этом. Как только условие перехода будет вычислено, процессор может прервать эти команды, если предсказание было неверным. Предположим, что мы предсказали, что условный переход не будет выполнен, и продолжили выполнять команды в порядке следования. Если окажется, что переход должен был быть выполнен, то конвейер должен быть очищен (flushed) от трех команд, идущих сразу за командой перехода, путем очистки соответствующих временных регистров конвейера. Зря потраченные в этом случае такты называются простоем из-за неправильно предсказанного перехода (branch misp rediction penalty).
На рис. 1.20 показано, что происходит в конвейере, если выполнен условный переход из адреса 20 по адресу 64. Условие перехода вычисляется на четвертом такте; к этому моменту процессор уже выбрал команды and, or и sub из адресов 24, 28, и 2C соответственно.
Конвейер должен быть очищен от этих команд, после чего на пятом такте будет выбрана команда slt по адресу 64.
47
Рис. 1.20. Очистка конвейера при выполненном условном переходе
Мы могли бы уменьшить простой из-за неправильно предсказанного перехода, если бы могли вычислить условие перехода пораньше. Так как вычисление условия заключается в определении равенства двух регистров, то мы могли бы использовать отдельный компаратор – это гораздо быстрее, чем вычитать два числа и проверять результат на равенство нулю. Если компаратор достаточно быстр, то можно перенести его в стадию Decode, чтобы прочитанные из регистрового файла операнды тут же сравнивались, а результат сравнения использовался для вычисления нового значения счетчика команд к концу стадии
Decode.
На рис. 1.21показано функционирование конвейера с ранним вычислением условий перехода, происходящим на втором такте. На третьем такте процессор очищает конвейер от команды and и выбирает из памяти команду slt, то есть простой из-за неправильно предсказанного перехода уменьшился с трех тактов до одного.
На рис. 1.22 показан конвейерный процессор с ранним вычислением условий переходов, способный разрешать конфликты управления. В стадию Decode добавлен компаратор, туда же перенесен и логический элемент И, используемый для получения сигнала PCSrc, так что теперь PCSrc формируется в стадии Decode, а не Memory, как раньше. Чтобы адрес перехода PCBranch был вычислен
48
вовремя, соответствующий сумматор тоже должен быть перенесен в стадию Decode. Для того чтобы очистить стадию Decode от ошибочно выбранной команды в случае неправильно предсказанного пере-
хода, нужно добавить вход синхронного сброса |
для |
вре- |
менного регистра, находящегося между стадиями |
Fetch |
и |
Decode, и подключить его к сигналу PCSrcD. |
|
|
Рис. 1.21. Раннее вычисление условия перехода
Рис. 1.22. Разрешение конфликтов управления в конвейере
49
Таким образом, конфликты при чтении данных после записи (RAWdatahazards) случаются, когда одна из команд зависит от результата предыдущей команды, еще не записанного в регистровый файл. Такие конфликты можно разрешить при помощи байпаса, если результат вычислен достаточно рано; в противном случае потребуется приостановка конвейера до тех пор, пока он не будет готов. Конфликты управления возникают, когда нужно выбрать из памяти команду, а решение о том, какую именно, еще не принято. Эти конфликты разрешаются путем предсказания того, какая именно команда должна быть выбрана, и очисткой конвейера от ошибочно выбранных команд в случае, если предсказание не сбылось. Количество команд, от которых придется очистить конвейер в случае неправильно предсказанного перехода, минимизируется путем перемещения логики вычисления условия переходов в начало конвейера. Как вы могли заметить, при разработке конвейерных процессоров нужно понимать, как различные команды могут взаимодействовать между собой, а так же заранее обнаружить все возможные конфликты.
2.ПРОГРАММИРОВАНИЕ
2.1.Типы инструкций. Общие сведения
Язык ассемблера удобен для чтения человеком, но цифровые схемы понимают только нули и единицы. Поэтому программу, написанную на языке ассемблера, переводят из последовательности мнемоник в последовательность нулей и единиц, которую называют машинным языком.
Для простоты нужно придерживаться единообразия, и наиболее единообразным представлением команд в машинном языке было бы такое, где каждая команда занимала бы ровно одно слово памяти.
50