Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
MProc / M9 / Оптимизация часть 4..doc
Скачиваний:
43
Добавлен:
16.04.2013
Размер:
124 Кб
Скачать

4.2.3.2. Предикация вне пути

Если транслятор имеет информацию динамического профиля, то возможно формирование планирования инструкций основывающееся на пути потока управления, который является наиболее вероятным для выполнения. Этот путь называется трассой (trace). В некоторых случаях, часто выполняются пути выполнения находящиеся не на главной трассе, и таким образом, может быть выгодно, использовать предикацию для минимизации их критических путей.

На рис. 4.1 выделена главная трасса потокового графа. Хотя блоки A и B не находятся на главной трассе, предположим, что они выполняются существенное количество раз.

Блок B

Блок A

Рис. 4.1. Граф потока, иллюстрирующий возможности предикации вне пути

Если некоторые инструкции в блоке A или в блоке B могут быть включены в главную трассу без увеличения критического пути, то могут применяться методы перемещения кода вверх, для уменьшения критического пути через блоки A и B, когда они принимаются. В следующем разделе дается пример того, как использовать предикацию как инструмент перемещения кода вверх.

4.2.3.3. Перемещение кода вверх.

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

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

(p1) br.cond some_label // Такт 0

st4 [r34] = r23 // Такт 1

ld4 r5 = [r56] // Такт 1

ld4 r6 = [r57] // Такт 2:в такте 1 нет свободных слотов M-типа

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

Примечание. Неоднозначные загрузки являются барьерами, через которые не могут продвигаться нормальные загрузки. В этом случае, перемещение загрузки также освобождает слот М-типа. Перезапишем код так, чтобы сохранение предшествовало переходу, при этом, p2 назначается дополняющим к р1:

(p2) st4 [r34] = r23 // Такт 0

(p2) ld4 r5 = [r56] // Такт 0

(p1) br.cond some_label // Такт 0

ld4 r6 = [r57] // Такт 1

Так как теперь сохранение имеет предикат, то невозможны никакие ошибки и исключения при принятии перехода и состояние памяти модифицируется только тогда, когда выполняется сохранение в блоке первоначального вида. Аналогично тому, как было передвинуто сохранение, можно передвинуть и инструкцию загрузки, без использования предварительной или спекулятивной загрузки (если только r5 не используется в принятом пути перехода).