
5.4.2. Предикация
Еще одна особенность архитектуры IA-64 - новый способ обработки условных переходов. Вообще чем таких команд меньше, тем центральный процессор становится проще и работает быстрее. На первый взгляд устранить условные переходы невозможно, поскольку в программах всегда много операторов if. Однако в архитектуре IA-64 используется специальная технология, названная предикацией, которая позволяет существенно сократить их число.
В современных ЭВМ все команды являются безусловными в том смысле, что когда центральный процессор выбирает команду, он ее просто выполняет. Здесь никогда не решается вопрос “выполнять или не выполнять?”. В архитектуре с предикацией команды содержат условия, которые сообщают, в каком случае нужно выполнять команду, а в каком - нет. Замена безусловных команд командами с предикацией позволяет избавиться от многих условных переходов. Вместо того чтобы выбирать ту или иную последовательность безусловных команд, все команды рассматриваются как одна последовательность команд с предикацией.
Для понимания этой идеи рассмотрим пример, в котором показано условное выполнение команд. Оператор if:
if (Rl == 0) R2 = R3;
соответствующий код на ассемблере:
CMP R1, 0
BNE L1
MOV R2, R3
L1:
Использование условной команды:
CMOVZ R2, R3, R1
Условная команда CMOVZ проверяет, равен ли третий регистр (R1) нулю. Если да, то команда копирует R3 в R2. Если нет, то команда не выполняет никаких действий.
Соответственно может иметься и команда, которая копирует данные, если заданный регистр не равен нулю (например, CMOVN). При наличии обеих команд можно транслировать полный оператор if без использования условных переходов. Полученные команды можно даже переупорядочить при компиляции или во время выполнения. Единственное требование при этом состоит в том, чтобы условие было известно к тому моменту, когда результаты условных команд нужно будет помещать в выходные регистры (то есть обычно в конце конвейера).
Оператор if:
if (Rl ==0) { R2=R3: R4=R5; }
else { R6=R7; R8=R9; }
код на ассемблере:
CMP R1, 0
BNE L1
MOV R2, R3
MOV R4, R5
BR L2
L1: MOV R6, R7
MOV R8, R9
L2:
условное выполнение:
CMOVZ R2, R3, R1
CMOVZ R4, R5, R1
CMOVN R6, R7, R1
CMOVN R8, R9, R1
Здесь показаны лишь очень простые условные команды (взятые из Pentium II), однако в архитектуре IA-64 все команды являются предикатными. Дополнительное 6-битное поле в команде, о котором сказано выше, содержит номер одного из 64-х 1-битных предикатных регистров. Таким образом, любой оператор if может быть скомпилирован в код, который устанавливает один из предикатных регистров в 1, если условие истинно, и в 0, если условие ложно. Одновременно с этим автоматически устанавливается другой предикатный регистр в обратное значение. При использовании предикации машинные команды, реализующие ветки then и else, будут помещаться в единый поток команд, часть из них - с использованием самого предиката, остальная часть - с использованием его обратного значения.
Следующий пример показывает использование предикации для устранения переходов. Команда CMPEQ сравнивает два регистра и устанавливает предикатный регистр P4 в 1, если операнды равны, и в 0, если они не равны. Кроме того, команда устанавливает парный регистр, например Р5, в обратное условие. Теперь команды частей if и then можно поместить одну за другой, причем каждая из них связывается с каким-нибудь предикатным регистром (регистр указывается в угловых скобках). Сюда можно поместить любой код, при условии что каждая команда предсказывается правильно.
Оператор if:
if (Rl == R2) R3 = R4 + R5;
else R6 = R4 - R5;
код на ассемблере:
CMP R1, R2
BNE L1
MOV R3, R4
ADD R3, R5
BR L2
L1: MOV R6, R4
SUB R6, R5
L2:
выполнение с предикацией:
CMPEQ R1, R2, P4
<Р4> ADD R3, R4, R5
<Р5> SUB R6, R4, R5
В архитектуре IA-64 изложенная идея доведена до логического завершения: здесь с предикатными регистрами связаны команды сравнения, арифметические, а также некоторые другие команды. Команды с предикацией могут свободно помещаться в конвейер без простаиваний. Каждая команда действительно выполняется, а в самом конце конвейера, когда нужно сохранять результат в выходном регистре, производится проверка предикатного регистра. Результаты записываются в выходной регистр только при его истинности.