Немного поигрался с довольно редко испольуземой при разработке приложений дерективой компилятора __builtin_expect. Эта директива поддерживатеся как Clang, так и в GCC, а в случае с MSVC есть довольно похожая директива __assume, работающая только для switch, и которую, если верить MSDN, использовать не рекомендутся, так как она ведет к потенциальным проблемам. Сказать насколько может быть полезна директива __builtin_expect сложно, но мало ли, к примеру товарищу на моем любимом форуме это зачем-то понадобилось.
Немного о самой __builtin_expect. При генерировании ассемблерных инструкций, компилятор самостоятельно решает о том, какая из ветвей условия должна быть размещена в начале, а к какой необходимо перейти посредством условного перехода. Данное поведение никак не регламентируется стандартом и полностью зависит не только от компилятора, но и от выбранного уровня оптимизации, в чем можно легко убедится получив несколько ассемблерных листингов одного и того же кода. При помощи же __builtin_expect можно указать компилятору какую из ветвей в условии if-else или switch-case разместить первой, а на какую организовать условный переход.
Для тестов пришлось немного нагородить кода, так как при включеной оптимизации компилятор выкидывает все с его точки зрения лишнее. В данном примере директева __builtin_expect говорит компилятору о том, что в начале надо разместить код условия else, а только потом if.
foo1(1);
else
foo2(2);
И соответствующий кусок ассемблерного кода.
jg LBB2_1
## BB#2: ## %if.else
mov EDI, 2
pop RBP
jmp __Z4foo2i ## TAILCALL
LBB2_1: ## %if.then
mov EDI, 1
pop RBP
jmp __Z4foo1i ## TAILCALL
Лично я помню только один случай и своего опыта, когда подобное поведение бы мне пригодилось. Тогда я писал перекодировку межде графическими форматами и у меня почти всегда выполнялось определенное условие, причем проверка вызывалась очень часто.
тут есть одна тонкость – нынешние процессоры умеют предсказывать условные переходы, и время выполнения перехода больше зависит от удачности предсказания а не того, произойдёт ли он. поэтому сэкономить на этом очень сложно, разве что у вас всего несколько ассемблерных команд, повторяемых в цикле
вообще есть книги Агнера Фога о микроархитектруре разных x86 – советую почитать, хотя бы ради интеллектуального удовольствия
Спасибо за рекомендацию, почитаю!