Я пишу аудио-код, где в основном все представляет собой крошечный цикл. Сбои предсказания ветвлений, насколько я понимаю, — это достаточно большая проблема производительности, из-за которой я стараюсь сохранить свободную ветвь кода. Но есть только то, что может взять меня, что заставило меня задуматься о различных видах ветвления.
В c ++ условный переход к фиксированной цели:
int cond_fixed(bool p) {
if (p) return 10;
return 20;
}
И (если я понимаю этот вопрос правильно), безусловный переход к переменной target:
struct base {
virtual int foo() = 0;
};
struct a : public base {
int foo() { return 10; }
};
struct b : public base {
int foo() { return 20; }
};
int uncond_var(base* p) {
return p->foo();
}
Есть ли различия в производительности? Мне кажется, что если бы один из двух методов был явно быстрее другого, компилятор просто преобразовал бы соответствующий код.
Для тех случаев, когда прогнозирование ветвления имеет очень большое значение, какие детали относительно производительности полезно знать?
РЕДАКТИРОВАТЬ: Фактическая операция x : 10 ? 20
это просто заполнитель. Фактическая операция, следующая за веткой, является, по крайней мере, достаточно сложной, чтобы выполнять обе эти операции неэффективно. Кроме того, если у меня было достаточно информации, чтобы разумно использовать __builtin_expect
прогнозирование ветвления не будет проблемой в этом случае.
Примечание: если у вас есть такой код
if (p) a = 20; else a = 10;
тогда нет никакой ветви. Компилятор использует условный ход (см .: Почему условный ход не уязвим для ошибки прогнозирования ветвления?)
Вы не упомянули свой компилятор. Однажды я использовал GCC для приложения, критичного к производительности (на самом деле конкурс в моем университете), и я помню, что GCC имеет __builtin_expect
макро. Я выполнил все условия в своем коде и в итоге получил ускорение на 5-10%, что показалось мне поразительным, учитывая тот факт, что я обратил внимание практически на все, что знал (макет памяти и т. Д.) И что не сделал ничего не меняйте в отношении самого алгоритма.
Кстати, алгоритм был довольно простым поиском глубины. И я запустил его на Core 2 Duo, хотя не уверен, какие именно.