Скачиваний:
58
Добавлен:
16.04.2013
Размер:
260.1 Кб
Скачать

5.5. Оптимизация циклов в архитектуре IntelItanium

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

5.5.1. While-циклы

Схема программирования для while-циклов зависит от структуры цикла. В этом разделе обсуждаютсяdo-while-циклы, в которых условие цикла вычисляется в конце цикла. Оптимизирующие трансляторы часто преобразуютwhile-циклы (где условие вычисляется вверху цикла) вdo-while-циклы, перемещая вычисление условия в подножие цикла и размещая перед циклом копию вычисления условия, чтобы уменьшить количество переходов в цикле. Остальная часть этого раздела описывает такие циклы, просто, какwhile-циклы. Ниже приведен простойwhile-цикл.

L1: ld4 r4 = [r5],4;; // Такт 0

st4 [r6] = r4,4 // Такт 2

cmp.ne p1,p0 = r4,r0 // Такт 2

(p1) br L1;; // Такт 2

Концептуальное представление конвейерной итерации этого цикла с ИИ равным единице, выглядит так:

stage 1: ld4 r4 = [r5],4

stage 2: --- // пустая стадия

stage 3: st4 [r6]= r4,4

cmp.ne.unc p1,p0 = r4,r0

(p1) br L1

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

1

2

3

4

Такт

ld4

X

ld4.s

X+1

scb

ld4.s

X+2

scb

ld4.s

X+3

scb

X+4

scb

X+5

Обратите внимание, что загрузка для второй исходной итерации выполняется до сравнения и перехода первой исходной итерации. То есть, загрузка (и модификация r5) является спекулятивной. Условие цикла не вычисляется до такта Х+2, но чтобы максимизировать использование ресурсов, желательно запустить вторую исходную итерацию на такте Х+1. Без поддержки спекуляции по управлению, имеющейся вItaniumархитектуре, вторая исходная итерация не смогла бы начаться до такта Х+3.

Вычисление условия цикла для while-циклов очень отличается от такового для счетных циклов. В счетных циклах, можно вычислить условие цикла за один такт, используя подсчет циклических переходов. Это то, что делает инструкцияbr.ctop, когда устанавливаетр16. Вwhile-циклах, сравнение должно вычислить условие цикла и установить предикаты стадий. Стадии, предшествующие первому сравнению, называютсяспекулятивными стадиямиконвейера, поскольку здесь не возможно сравнение для полного управления выполнением этих стадий. Поэтому, предикат стадии, установленный сравнением, используется (после ротации) для управления первой не спекулятивной стадией конвейера.

Ниже показана конвейерная версия предыдущего while-цикла. Для спекулятивной загрузки вставлена проверка:

mov ec = 2

mov pr.rot = 1 << 16;; // PR16 = 1, остальные = 0

L1:

ld4.s r32 = [r5],4 // Такт 0

(p18) chk.s r34, recovery // Такт 0

(p18) cmp.ne p17,p0 = r34,r0 // Такт 0

(p18) st4 [r6] = r34,4 // Такт 0

(p17) br.wtop.sptk L1;; // Такт 0

L2:

Чтобы объяснить, почему ядерный цикл запрограммирован таким образом, полезно исследовать трассу выполнения цикла (в предположении, что имеется 200 исходных итераций), показанную в табл. 5.2.

Здесь нет предиката стадии предназначенного для загрузки, потому что она спекулятивна. Сравнение устанавливает р17. Он является предикатом перехода для текущей итерации, а после ротации – предикатом стадии для первой не спекулятивной стадии (стадии 3) следующей исходной итерации. В течение стадии пролога, сравнение не может быть выполнено, его первый правильный результат появится со второго такта. Инициализация предикатов обеспечивает конвейер, который запрещает сравнение до тех пор, пока первая исходная итерация не достигнет стадии два на втором такте. В этой точке сравнение начнет генерировать предикаты стадий для управления не спекулятивными стадиями конвейера. Обратите внимание, что сравнение условно. Если бы оно было безусловным, то всегда записывало бы 0 вр17,и конвейер не начался бы правильно.

Табл. 5.1. Трассировка цикла wtop

Цикл

Порт/Инструкции

Состояние перед br.wtop

M

I

I

M

B

p16

p17

p18

EC

0

ld4.s

br.wtop

1

0

0

2

1

ld4.s

br.wtop

0

1

0

1

2

ld4.s

cmp

chk

st4

br.wtop

0

1

1

1

3

ld4.s

cmp

chk

st4

br.wtop

0

1

1

1

100

ld4.s

cmp

chk

st4

br.wtop

0

1

1

1

199

ld4.s

cmp

chk

st4

br.wtop

0

1

1

1

200

ld4.s

cmp

chk

st4

br.wtop

0

1

1

1

201

ld4.s

cmp

chk

st4

br.wtop

0

0

1

1

0

0

0

0

Выполнение br.wtopв двух первых тактах пролога, не соответствует ни какой исходной итерации. Их цель – просто продолжить выполнение до тех пор, пока не будет произведено первое правильное условие цикла. На первом такте предикат переходар17равен 1. Для этой схемы программирования, предикат переходаbr.wtopвсегда единица в течение последней спекулятивной стадии первой исходной итерации. В течение всех предшествующих стадий предикат перехода равен нулю. Если предикат перехода – ноль, тоbr.wtopпродолжает ядерный цикл, только если ЕС больше единицы. Здесь же ЕС декрементируется. Таким образом, регистр ЕС должен инициализироваться значением равным количеству стадий эпилога, плюс количество спекулятивных конвейерных стадий. В вышеупомянутом примере, это будет: 0 + 2 = 2.

В такте 201, выполняется сравнение для 200-ой исходной итерации. Поскольку это финальная исходная итерация, то результат сравнения – ноль, а р17не модифицируется. Ноль, который ротируется изр17вр16, вызывает проход черезbr.wtopк выходу из цикла. ЕС декрементируется, а регистры ротируются последний раз.

В вышеприведенном примере нет стадий эпилога. Как только предикат становиться нулевым – выходим из ядерного цикла.