Детальный проект конвейерного RISC процессора (Глава 4 "Основы конвейеризации"), страница 25

4.6.3    Слоты задержки команд Branch/Jump (Ветвления/перхода)

Задача оптимизирующего компилятора – хорошо использовать слоты задержки branch/jump. В более простом случае компилятор заполняет слоты задержки командой NOP, но компилятор может работать лучше (таблица 4.19, [HP96]). Он пытается заполнить слоты задержки полезными командами. Существуют три основных кодовых блока для выбора команд, а именно:

1. Кодовый блок, который непосредственно предшествует branch/jump. Слот задержки может быть заполнен командами не-ветвления из этого блока, если переход не зависит от переупорядочивания команд, и если зависимости данных к другим командам разрешают переупорядочивание. Это всегда улучшает производительность по сравнению с использованием NOP.

2. Код из адреса назначения команд branch/jumpПереупорядоченная команда не должна перезаписать данные, которые все еще необходимы в случае, если ветвление не принимается. Эта оптимизация улучшает производительность, только если ветвление принимается; иначе работа слота задержки потрачена впустую.

3. Код из провалившегося условного ветвления. По аналогии со вторым случаем, переупорядоченная команда не должна перезаписать данные, если ветвление принято. Эта оптимизация улучшает производительность, только если ветвление не принято.

Стратегия 1 – лучший выбор. Две другие стратегии используются только тогда, когда первая не применима. Насколько хорошо слот задержки может быть заполнен также зависит от типа команды branch/jump:

• Безусловный относительный branch/jump всегда принимается и имеет фиксированный адрес назначения. Таким образом, если первая стратегия не работает, команда назначения может быть использована для заполнения слота задержки.

• Безусловный абсолютный переход всегда принимается, но адрес назначения может изменяться. Этот тип перехода обычно выполняется при вызове процедуры или возврате из процедуры. В этом случае существует множество независимых команд, которые могут быть спланированы в слот задержки, например, команды для пропуска параметра/результата.


Таблица 4.19 Процент условных переходов в SPECint92 и насколько хорошо слот задержки (DS) может быть заполнен. AV означает арифметическое среднее по этим пяти эталонным тестам.


                  compress

eqntott

espresso

gcc

li       |   AV

% branch

17.4

24.0

15.2

11.6

14.8

16.6

empty DS

49%

74%

48%

49%

75%

59%

Таблица 4.20 Смешение команд [%] программы SPECint92 нормализованное до 100%.

команды

compress

eqntott

espresso

gcc

li

AV

загрузка

19.9

30.7

21.1

23.0

31.6

25.3

хранение

5.6

0.6

5.1

14.4

16.9

8.5

вычисление

55.4

42.8

57.2

47.1

28.3

46.2

вызов (jal, jalr)

0.1

0.5

0.4

1.1

3.1

1.0

переход

1.6

1.4

1.0

2.8

5.3

2.4

ветвления, принятые

12.7

17.0

9.1

7.0

7.0

10.6

~, непринятые

4.7

7.0

6.1

4.6

7.8

6.0

• Условные ветвления. Если переход является результатом конструкции if-then-else, очень сложно предсказать поведение перехода во время компиляции. Таким образом, если первая стратегия не работает, слот задержки может быть едва заполнен полезной командой. Для циклов предсказание переходов намного проще поскольку тело цикла обычно выполняется несколько раз.

Таким образом, слот задержки безусловного ветвления/перехода может быть всегда заполненным; только условные ветвления являются причиной некоторых проблем. Для этих ветвлений, компилятор может заполнить приблизительно только 40% слотов задержки (таблица 4.19).