поиск максимума среди двух целых чисел без использования ветвлений
Компилятор msvc поддерживает замену ветвлений математическими операциями, однако, использует несколько другую технику, отдавая предпочтение инструкции SETcc, устанавливающая переменную в единицу, если условие сс истинно. Как показывает практика, msvc оптимизирует только ветвления константного типа, т. е. "if (n >
m) a = 66; else a = 99;" еще оптимизируется, а "if (n >
m) a = x; else a = y;" уже нет.
Компилятор gcc, использующий инструкцию условного присвоения CMOVcc, оптимизирует все конструкции типа min, max, set flags, abs и т. д., что существенно увеличивает производительность, однако, требует как минимум Pentium Pro (инструкция SETcc работает и на Intel 80386). За это отвечают ключи -fif-conversion
и -fif-conversion2, которые на платформе Intel эквивалентны друг другу. (Вообще говоря, gcc поддерживает множество ключей, отвечающих за ликвидацию ветвлений, однако, на платформе Intel они лишены смысла, поскольку в лексиконе x86 процессоров просто нет соответствующих команд, это вам не PDP?11, элегантность которой остается непревзойденной до сих пор и которая имена специальную команду "пропустить следующую машинную инструкцию, если условие cc истинно/ложно", — вот где был простор для избавления от ветвлений!).
Компилятор icl – единственный из всех трех, кто не заменяет ветвления математическими операциями (что в свете активной агитации за команды SBB/CMOVcc, развернутой компаний Intel, выглядит довольно странно). Во всяком случае компилятор не делает этого явно и в качестве компенсации предлагает использовать инстриксы и функции мультимедийной библиотеки SIMD. В частности, цикл вида:
short a[4], b[4], c[4];
for (i=0; i<4; i++)
c[i] = a[i] >
b[i] ? a[i] : b[i];