Серверы корпоративных баз данных


Параллелизм на уровне выполнения - часть 4


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

Loop: LD F0,0(R1) ;F0=элемент вектора

ADDD F4,F0,F2 ;добавляет скаляр из F2

SD 0(R1),F4 ;запись результата

SUBI R1,R1,#8 ;пересчитать указатель

;8 байт (в двойном слове)

BNEZ R1, Loop ;переход R1!=нулю

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

Рассмотрим работу этого цикла при выполнении на простом конвейере с задержками, показанными на рисунке 3.12.

Если не делать никакого планирования, работа цикла будет выглядеть следующим образом:

Такт выдачи

Loop: LD F0,0(R1) 1

приостановка 2

ADDD F4,F0,F2 3

приостановка 4

приостановка 5

SD 0(R1),F4 6

SUBI R1,R1,#8 7

BNEZ R1,Loop 8

приостановка 9

Для его выполнения потребуется 9 тактов на итерацию: одна приостановка для команды LD, две для команды ADDD, и одна для задержанного перехода. Мы можем спланировать цикл так, чтобы получить

Loop: LD F0,0(R1) 1

приостановка 2

ADDD F4,F0,F2 3

SUBI R1,R1,#8 4

BNEZ R1,Loop ;задержанный переход 5

SD 8(R1),F4 ;команда изменяется, когда 6

;меняется местами с командой SUB1

Время выполнения уменьшилось с 9 до 6 тактов.

Заметим, что для планирования задержанного перехода компилятор должен определить, что он может поменять местами команды SUB1 и SD путем изменения адреса в команде записи SD: Адрес был равен 0(R1), а теперь равен 8(R1). Это не тривиальная задача, поскольку большинство компиляторов будут видеть, что команда SD зависит от SUB1, и откажутся от такой перестановки мест. Более изощренный компилятор смог бы рассчитать отношения и выполнить перестановку. Цепочка зависимостей от команды LD к команде ADDD и далее к команде SD определяет количество тактов, необходимое для данного цикла.

В вышеприведенном примере мы завершаем одну итерацию цикла и выполняем запись одного элемента вектора каждые 6 тактов, но действительная работа по обработке элемента вектора отнимает только 3 из этих 6 тактов (загрузка, сложение и запись).


Начало  Назад  Вперед



Книжный магазин