23. Классификация конвейерных конфликтов. Методы преодоления конфликтов по управлению.
Конфликты по управлению – конфликты, в которых выполнение или невыполнение инструкции зависит от решения, принятого более ранней инструкцией конвейера. Примеры: инструкции условного перехода, вызовы процедур, инструкции безусловного перехода, исключительные ситуации. Ветвления составляют 20% от всех инструкций.
Проблема: инструкции ветвления и инструкции безусловных переходов приводят к очистке конвейера (что, например, в случае Pentium 4 приведет к потере порядка 20 циклов).
Преодоление конфликтов по управлению:
- Ожидание (stall, Lazy Execution), возврат.
- «Быстрые» инструкции ветвления.
- Задержанные переходы (Delayed Branch) – в архитектуре вводится правило: k инструкций после инструкции ветвления выполняются обязательно.
- Условные команды.
- Упреждающее исполнение (Speculative Execution).
Ожидание: никаких мер не предпринимается до тех пор пока не
будет определен адрес перехода.
Возврат: процессор продолжает выполнение, как будто перехода
не было, если переход оказывается выполняемым, результат
отбрасывается. Противоположный вариант рассматривает
каждый переход как выполняемый, а в остальном работает
аналогично.
Быстрые инструкции ветвления: переходы определяются на
стадии Fetch. Это требует аппаратной поддержки и простого
формата инструкций ветвления.
Задержанные переходы (Delayed Branch) – в архитектуре предусматривается правило: k инструкций после инструкции ветвления выполняются обязательно (где k – число тактов от выборки инструкции ветвления до определения адреса перехода). Слоты для этих инструкций выбираются компилятором среди инструкций, предшествующих ветвлению.
Упреждающее (спекулятивное) исполнение
Упреждающее (спекулятивное) исполнение – выполнение кода, раньше момента, когда станет известно, что его действительно надо выполнять. Требует поддержки со стороны аппаратуры и со стороны компилятора.
Разновидности:
- Выполнение по предсказанию (Predictive Execution) – заранее начинается выполнение одной из ветвей, а если прогноз не оправдался результаты отбрасываются.
- «Нетерпеливое выполнение» (Eager execution) – выполняются по одной инструкции каждой ветви, затем результат невыбранной ветви отбрасывается.
В случае упреждающего выполнения огромное значение приобретает точность предсказаний. Поддержка компилятора нужна для перестановки команд в базовых блоках: переноса инструкции чтения из памяти до ветвления, исправляющих инструкций для устранения ошибок предсказания.
Существует проблема обработки исключений.
Загрузка слова из памяти может вызвать промах кэша или страничное исключение. Некоторые решения: специальные инструкции Speculative-Load, загружающие слово из кэша, но ничего не выполняющие в случае промаха. Мелкие расходы, например, доступ к кэшу 1-го уровня приемлемы, крупные же откладываются до момента, когда станет очевидной их неизбежность.
Исключения наподобие Zero Division могут разрешаться с помощью Poison Bit: в архитектуре используются специальные версии инструкций, вызывающих исключения, Poison Bit добавляется к каждому регистру. Если спекулятивное исполнение вызывает исключение, то для регистра результата устанавливается Poison Bit. Если регистр позже используется обычной инструкцией, то вызывается прерывание.
Упреждающее исполнение и задача обеспечения энергоэффективности
Спекулятивное выполнение повышает энергопотребление в двух случаях:
- Выполненные с упреждением инструкции оказались не нужны.
- Отмена действий и восстановление состояния процессора из-за упреждения.
Вывод: при необходимости обеспечения пониженного энергопотребления нужно либо избегать упреждающего выполнения, либо искать более точные методы предсказания, либо искать новые подходы.