Как нулевой регистр улучшает производительность?

В MIPS ISA есть нулевой регистр ($r0), который всегда дает значение ноль. Это позволяет процессору:

  1. Любая инструкция, которая дает результат, который должен быть отброшен, может направить свою цель в этот регистр
  2. Быть источником 0

В этом источнике говорится, что это улучшило скорость процессора. Как это улучшает производительность? И по каким причинам не все ISA принимают этот нулевой регистр?

$ r0 не общего назначения. Он привязан к 0. Независимо от того, что вы делаете с этим регистром, он всегда имеет значение 0. Вы можете задаться вопросом, зачем такой регистр необходим в MIPS.

Разработчики MIPS использовали эталонные тесты (программы, используемые для определения производительности ЦП), которые убедили их в том, что наличие регистра, встроенного в 0, повысит производительность (скорость) ЦП, а не его отсутствие. Не все согласны с тем, что регистр, привязанный к 0, необходим, поэтому не все ISA имеют нулевой регистр.

3 ответа

Решение

Есть несколько возможных способов улучшить производительность. не ясно, какие из них применимы к этому конкретному процессору, но я перечислил их примерно по порядку от наиболее вероятных до наименее вероятных.

  1. Это позволяет избежать ложных трубопроводов. Без явного нулевого регистра необходимо взять регистр, обнулить его и использовать его значение. Это означает, что операция использования нуля зависит от операции обнуления и (в зависимости от того, насколько мощной является система пересылки конвейера), возможно, от предыдущего значения обнуленного регистра. Такие архитектуры, как x86, которые имеют довольно маленькие файлы регистров и в основном виртуализируют свои регистры, чтобы избежать возникновения проблем, имеют чрезвычайно мощные инструменты анализа рисков. То же самое обычно не относится к процессорам RISC.
  2. Некоторые операции могут быть более конвейерными, если они могут избежать чтения регистра. Если используется явный нулевой регистр, тот факт, что операнд будет нулевым, известен на этапе декодирования инструкций, а не позднее на этапе выборки регистров. Таким образом, этап чтения регистра может быть пропущен.
  3. Аналогичным образом, возможность явного отбрасывания результатов исключает необходимость стадии записи в регистр.
  4. Некоторые операции могут генерировать более простой микрокод, когда известно, что один из их операндов равен нулю или когда известно, что результат отбрасывается.
  5. Явный регистр нуля снимает некоторое напряжение с оптимизатора компилятора, так как ему не нужно быть столь же осторожным с назначением регистров (не нужно идентифицировать регистр, который не вызовет остановки при чтении или записи).

Для каждого из ваших пунктов вот ответ.

  1. Рассмотрим инструкции, которые обязательно берут регистр для вывода, где вы хотите отбросить этот вывод. Обычно вам нужно убедиться, что у вас есть свободный регистр, а если нет, перенести некоторые из ваших текущих регистров в стек, что является дорогостоящей операцией. Очевидно, что часто случается, что вывод операций отбрасывается, и самый простой способ справиться с этим - это иметь "неиспользуемый" регистр.
  2. Теперь, когда у нас есть такой неиспользованный регистр, почему бы не использовать его? Часто случается так, что вы хотите что-то инициализировать или сравнить с нулем. Долгий путь - сначала записать ноль в этот регистр (который требует дополнительной инструкции и литерала для нуля в вашем машинном коде, который может иметь вид 0x00000000 что довольно долго), а затем использовать его. Итак, одна инструкция сбрила и немного размера вашей программы.

Эти оптимизации могут показаться немного тривиальными и могут поставить вопрос: "Насколько это на самом деле что-то улучшает?" Ответ здесь заключается в том, что описанные выше операции, очевидно, часто используются на вашем процессоре MIPS.

Концепция нулевого регистра не нова. Я впервые столкнулся с ним на мэйнфрейме CDC 6600, который восходит к середине-концу 1960-х годов. В некотором смысле это был один из первых процессоров RISC, и он был самым быстрым компьютером в мире в течение 5 лет. В этой архитектуре регистр "B0" был жестко привязан к нулю. http://en.wikipedia.org/wiki/CDC_6600

Преимущество такого регистра прежде всего в том, что он упрощает набор команд. Когда декодирование и оркестровка простых и обычных наборов команд могут быть реализованы без микрокода, это увеличивает производительность. Кроме того, для 6600, как и для большинства современных микросхем LSI, время, затрачиваемое на прохождение сигнала по длине, которое становится "проводом", становится одним из ключевых факторов скорости выполнения, а простота набора команд (и исключение микрокода) позволяет использовать меньше транзисторов. и приводит к более коротким путям.

Нулевой регистр позволяет сохранить некоторые коды операций при разработке новой архитектуры набора команд (ISA).

Например, основная спецификация RISC-V содержит 32 псевдо-инструкции, которые зависят от нулевого регистра (см. Таблицы 26.2 и 26.3). Псевдо-инструкция - это инструкция, которая отображается ассемблером на другую реальную инструкцию (например, ветвь, если равно нулю, отображается на ветвь, если равно). Для сравнения: основная спецификация RISV-V перечисляет 164 реальных кода операций инструкций (т.е. считая RV(32|64)[IMAFD] base/extensions, aka RV64G). Это означает, что без нулевого регистра RISC-V RV64G занимал бы на 32 кода операции больше для этих инструкций (т.е. на 20 % больше). Для конкретной реализации ЦП RISC-V это соотношение реальных и псевдокоманд может сдвигаться в любом направлении в зависимости от того, какие расширения выбраны.

Использование меньшего количества кодов операций упрощает декодер команд.

Более сложный декодер требует больше времени для декодирования инструкций или занимает больше вентилей (которые нельзя использовать для более полезных блоков ЦП) или и того, и другого.

Существующие, постепенно развивающиеся ISA должны иметь дело с обратной совместимостью. Таким образом, если ваш исходный проект ISA не включает нулевой регистр, вы не можете просто добавить его в более позднюю версию без нарушения совместимости. Кроме того, если ваш существующий ISA уже требует очень сложного декодера, добавление нулевого регистра не окупается.

Помимо современного RISC-V ISA (разработанного с 2010 года, первая ратификация в 2019 году), ARMv8 AArch64 (64-битный ISA, выпущенный в 2011 году), в отличие от предыдущих 32-битных ISA ARM, также имеет нулевой регистр. Из-за этого и других изменений AArch64 ISA имеет гораздо меньше общего с предыдущими 32-разрядными ISA для ARM, чем, скажем, ISA для x86 и x86-64.

В отличие от AArch64, x86-64 не имеет нулевого регистра. Хотя x86-64 более современный, чем предыдущий 32-битный x86 ISA, его ISA изменялся только постепенно. Таким образом, он включает все существующие коды операций x86 плюс 64-битные варианты, и, следовательно, декодер уже очень сложен.

Другие вопросы по тегам