Основы вычислительных конвейеров, страница 10

Ω означает пустое множество (не содержащее никаких элементов).

То же показано на рисунках:

Помеха «чтение после записи».

Можно конкретизировать указанные условия, приведя перечень областей определения и множеств значений для каждого класса команд рассмотренной модели архитектуры:

Описанная выше модель архитектуры может не полностью представлять реальные архитектуры (например, при ассортименте косвенных адресаций), но она достаточна представительна и в следующей таблице перечислены все типы помех, которые только могут встретиться в ней между командами:

Примеры:

а)  команда STORE использует содержимое некоторого индексного регистра, вычисляемое предыдущей ADD; она способна порождать помеху RAW;

б)  две последовательно выполняемых команды JUMP дают помеху WAW, поскольку обе изменяю содержимое СК;

в)  команда BRANCH зависит от кода состояния или значения в регистре, выработанных предыдущей ADD; она не должна зависеть от кода состояния следующей команды => помеха WAR и т.д.

Еще одна особая помеха, не показанная в последней таблице, может возникать всякий раз, когда имеет место «самомодифицируемый код», т.е. когда некоторая команда (обычно STORE) записывает в память слово, которое (внимание!!) вскоре будет исполняться как команда. Такой код может создавать помеху RAW между командой с запоминанием (и/или STORE) и фазой выборки IFETCH команды, которая будет затем исполняться.

Помехи понятны. Разработчик обязан научить конвейер их фактически обнаруживать и устранять так, чтобы CPV работало, как того от него ожидают.

Приемов много. Все сводится к одному из стандартных классов.

Два противоположных подхода к проблеме обнаружения помехи:

1)  централизовать обнаружение помех на одной ступени (обычно выборки IFETCH) и сравнивать здесь область определения и множество значений команды с соответствующими областью определения и множеством значений для команд, уже находящихся в конвейере.

2)  позволить инициации команды двигаться по конвейеру до тех пор, пока она не достигнет точки, в которой требуется тот или иной элемент либо из области определения, либо из множества значений; и только тогда осуществляется проверка того, нет ли потенциальной помехи от другой команды, находящейся в конвейере.

Второй подход более гибкий, но аппаратные затраты для сравнений могут расти, как квадрат числа ступеней.

Два подхода и к устранению помех:

1)  просто «остановить конвейер», если найдена помеха: обнаружена команда j в состоянии помехи с ранее инициированной командой i; тогда останавливаются все инициации команд j, j+1, j+2, … до тех пор, пока команда i не пройдет через точку конфликта;

2)  (сложнее!!) останавливается команда j, но следующим (j+1, j+2,… ) разрешается двигаться по конвейеру; они обгоняют команду j, но на всех следующих ступенях для всех этих команд проверяется наличие помех не только с теми (до j), но и с j, и если здесь обнаруживается помеха, то выполнение этих команд откладывается до тех пор, пока «первая» исходная помеха для j не будет устранена и ей будет разрешено двигаться. Распадается на множество локальных методов, «изобретений», зачастую остроумных.

«Ускорение устранения помех типа RAW». Идет последовательность: …STORE, ADD, … Типичная помеха: ADD обращается к ячейке памяти, изменение содержимого которой осуществлялось STORE. Опасность! Помеха! Прямое решение: задержать ADD до окончания модификации со стороны STORE, а затем продолжать ADD.

Но есть быстрый способ, даже именуется «коротким замыканием»: копия данных, подлежащих запоминанию, передается прямо ADD! Это избавляет ADD от ожидания и затем выполнения еще одного чтения READ (хотя бы и внутри ADD):