addiu $6,$6,5
bltz $6,$L5
nop
...
$L5:
Это безопасно на MIPS I? Если да, то как?
Оригинальный MIPS I - это классическая 5-ступенчатая схема RISC IF ID EX MEM WB
, которая скрывает всю свою задержку ветвления с помощью одного слота задержки ветвления , проверяя условия ветвления на ранней стадии, на этапе ID. (Именно поэтому он ограничен равными / не равными или проверками битов знака, такими как lt или ge zero, а не lt между двумя регистрами, которые потребуют переноса через сумматор.)
Разве это не означает, что ветвям требуется, чтобы их вход был готов на цикл раньше, чем инструкции ALU? bltz
входит в стадию ID в том же цикле, в котором addiu
входит в EX.
MIPS I использует обходную переадресацию с EX-выхода на EX-вход, так что обычные целочисленные инструкции ALU (например, цепочка addu
/ xor
) имеют задержку одного цикла и могут выполняться последовательно циклы.
MIPS расшифровывается как «Микропроцессор без заблокированных ступеней трубопровода », поэтому он не обнаруживает опасности RAW; код должен их избегать. (Следовательно, слоты с задержкой загрузки в MIPS первого поколения, в MIPS II добавляются блокировки для остановки в этом случае, что делает акроним недействительным: P).
Но я никогда не вижу обсуждения расчета условия ветвления для нескольких инструкций впереди, чтобы избежать задержки. (Пример addiu / bltz был выдан MIPS gcc5.4 -O3 -march=mips1
на Godbolt , который не учитывает интервалы задержки загрузки, заполняя nop
при необходимости.)
Использует ли он какой-то трюк, такой как EX, считывающий входные данные на заднем фронте часов, и ID, которому не нужны переданные значения регистров до нарастающего фронта? (С EX производит свои результаты достаточно рано, чтобы это работало)
Полагаю, это имело бы смысл, если бы тактовая частота была достаточно низкой, чтобы доступ к кэшу был однократным.
Задержка или пузырь в MIPS утверждает, что lw
+ a beq
в результате загрузки требует 2 циклов остановки, потому что он не может пересылать. Это не точно для реальных MIPS I (если gcc не глючит). Однако в нем упоминаются полупериодические циклы, позволяющие записать значение и затем прочитать его из файла регистров за один и тот же полный цикл.