- •5. Программная конвейерная обработка и поддержка циклов
- •5.1. Краткий обзор
- •5.2. Терминология циклов и основная поддержка циклов
- •5.3. Оптимизация циклов
- •5.3.1. Развертывание цикла
- •5.3.2. Программная конвейерная обработка
- •5.4. Особенности поддержки циклов в архитектуре Intel Itanium
- •5.4.1. Ротация регистров
- •5.4.3. Переходы циклов с программной конвейерной обработкой
- •5.4.3.1. Переходы счетных циклов
- •5.4.2. Замечание об инициализации ротации предикатов
- •5.4.3.2. Пример счетного цикла
- •5.4.3.3. Переходы while-циклов
- •5.4.4. Краткий обзор терминологии
- •5.5. Оптимизация циклов в архитектуре Intel Itanium
- •5.5.1. While-циклы
- •5.5.2. Циклы с инструкциями, имеющими предикаты
- •5.5.3. Циклы с множеством выходов
- •5.5.3.1. Преобразование циклов с несколькими выходами в циклы с одним выходом.
- •5.5.3.2. Конвейерная обработка с явными многократными выходами
- •5.5.4. Соображения о программной конвейерной обработке
- •5.5.5. Программная конвейерная обработка и предварительные загрузки
- •5.5.5.1. Ограничения емкости
- •5.5.5.2. Конфликты в alat
- •5.5.6. Предварительное разворачивание циклов для программной конвейерной обработки
- •5.5.7. Осуществление сокращений
- •5.5.8. Явный пролог и эпилог
- •5.5.9. Устранение избыточной загрузки в циклах
- •5.6. Итоги
5.4. Особенности поддержки циклов в архитектуре Intel Itanium
В традиционной архитектуре, расширение кода, являющееся результатом оптимизации цикла (типа программной конвейерной обработки и развертывания цикла) может увеличивать количество промахов кэша инструкций, тем самым, сокращая общую эффективность. Особенности поддержки циклов в архитектуре Itanium позволяет применить к некоторым циклам программную конвейерную обработку без расширения кода. Ротация регистров обеспечивает механизм переименования, который уменьшает потребность в разворачивании цикла и программном переименовании регистров. Специальные переходы программной конвейерной обработки циклов поддерживают ротацию регистров и, совместно с предикацией, уменьшают необходимость генерировать отдельные блоки кода для фаз пролога и эпилога.
5.4.1. Ротация регистров
Ротация регистров переименовывает регистры путем добавления к номеру регистра значения регистра rrb (register rename base – база переименования регистров) содержащегося в CFM. Регистр rrb декрементируется, когда в конце каждой итерации ядра, выполняется некий специальный переход программной конвейерной обработки цикла. Декрементация регистра приводит к тому, что значение регистра Х кажется передвинутым в регистр Х+1. Если Х является наибольшим номером ротируемого регистра, то его значение циклически оборачивается к наименьшему номеру ротируемого регистра.
Для ротации определены области фиксированного размера в файлах предикатных регистров и регистров с плавающей точкой (p16-p63 и f32-f127), а также область программируемого размера в файле общих регистров. Размер ротируемой области в файле общих регистров задается непосредственным значением в инструкции alloc и должен быть числом кратным восьми, в диапазоне от 0 до 96. Наименьший номер ротируемого регистра в файле общих регистров – это r32. Регистр rrb поддерживается для каждого из трех ротируемых файлов: CFM.rrb.gr – для общих регистров; CFM.rrb.fr – для регистров с плавающей точкой; CFM.rrb.pr – для предикатных регистров. Переходы программной конвейерной обработки одновременно уменьшают все регистры rrb.
Ниже дан пример ротации регистров. Псевдоинструкция swp_branch представляет собой переход программной конвейерной обработки цикла:
L1: ld4 r35 = [r4],4 // постинкремент на 4
st4 [r5] = r37,4 // постинкремент на 4
swp_branch L1 ;;
Значение, которое записывается загрузкой в r35, через две итерации ядра (и через две ротации), читается сохранением как r37. За это время выполнятся еще две загрузки. Из-за ротации регистров их результаты запишутся в различные регистры и не изменят значение необходимое для сохранения.
Ротация предикатных регистров служит двум целям. Первая – избежать перезаписи значения предиката, которое всё еще необходимо. Вторая цель состоит в том, чтобы управлять заполнением и опустошением конвейера. Для этого программист назначает каждой стадии программного конвейера предикат, для управления выполнением инструкций на этой стадии. Этот предикат называется предикатом стадии. Для счетных циклов, р16 архитектурно определен как предикат для первой стадии, р17 определен как предикат для второй стадии и т.д. Ниже показан концептуальный вид исходной конвейерной итерации для исходного примера счетного цикла. Каждая стадия имеет длину в один такт, здесь же показаны предикаты стадий:
стадия 1:(p16) ld4 r4 = [r5],4
стадия 2:(p17) --- // пустая стадия
стадия 3:(p18) add r7 = r4,r9
стадия 4:(p19) st4 [r6] = r7,4
Ротация регистров происходит в конце каждой стадии (когда в ядерном цикле выполняется переход программного конвейерного цикла). Таким образом, единица, записанная в р16, разрешает первую стадию, а затем, в конце первой стадии, ротируется в р17 разрешая вторую стадию для той же самой исходной итерации. Каждая единица, записанная в р16, последовательно разрешает все фазы конвейерного цикла, в течение фаз пролога, ядра и эпилога, как описано в следующем разделе.
