2014-02-13 3 views
10

Я пишу какой-то аудио-код, где в основном все это крошечный цикл. Ошибки прогнозирования ветвей, как я их понимаю, - это довольно большая проблема с производительностью, и я изо всех сил стараюсь сохранить свободную ветку кода. Но до сих пор это может занять меня, что заставило меня задуматься о разных видах ветвления.Разница в производительности между предсказанием ветвей и предсказанием целевой ветви?

В C++, условный переход к фиксированной цели:

int cond_fixed(bool p) { 
    if (p) return 10; 
    return 20; 
} 

И (если я понимаю this question правильно), то безусловный переход к переменной цели:

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(); 
} 

Есть ли разница в производительности? Мне кажется, что если один из двух методов был, очевидно, быстрее другого, то компилятор просто преобразил бы код, чтобы он соответствовал.

Для тех случаев, когда предсказание ветвлений имеет очень большое значение, Какие сведения о производительности полезны для изучения?

EDIT: Реальная работа x : 10 ? 20 это просто место держатель. Фактическая операция, следующая за ветвью, является, по крайней мере, достаточно сложной, что выполнение обоих неэффективно. Кроме того, если бы у меня было достаточно информации, чтобы разумно использовать __builtin_expect, предсказание ветвления в этом случае было бы проблемой.

+0

Какой процессор? Какой компилятор? Вы проверили сборку, чтобы узнать, какая из двух стратегий была выбрана? –

+1

Примечание: компилятор не может преобразовать последний 'uncond_var', потому что он не знает полного набора возможных производных классов' base'. В общем случае * замкнутые * задачи (конечное число возможных входов) легче решить, чем * открытые *. –

+0

@ MatthieuM. Компилятор GCC, процессор - все, что угодно, от настольных до смартфонов, хотя современный настольный процессор - моя текущая проблема. Кроме того, мне кажется странным, что компилятор не знает всех возможных производных классов базы. Он имеет весь исходный код, поэтому эта информация существует. И нет, я недостаточно знаком с собранием, чтобы ощутить продуктивное погружение в такие детали. Вот почему я перехожу на этот сайт, чтобы надеяться получить более высокий уровень понимания от кого-то, кто знает такие детали. – porgarmingduod

ответ

1

Вы не указали свой компилятор. Я когда-то использовал GCC для приложения с критическими характеристиками (конкурс в моем университете фактически), и я помню, что GCC имеет макрос __builtin_expect. Я прошел все условия в своем коде и закончил с 5-10% ускорением, что, по моему мнению, было потрясающим, учитывая тот факт, что я обратил внимание на почти все, что я знал (макет памяти и т. Д.), И что я сделал ничего не измените в отношении самого алгоритма.

Алгоритм был довольно простым поиском глубины. И я запустил его на Core 2 Duo, но не уверен, какие из них.

+1

Примечание: что делает '__builtin_expect'? Учитывая этот намек, компилятор оптимизирует две вещи: 1/он может выстроить предсказание, а 2/может вывести код так, чтобы вероятный блок сразу же следовал за текущим блоком (чтобы минимизировать промахи в кэше). Очевидно, что одно предостережение состоит в том, что пострадают рабочие нагрузки, которые ведут себя так, как намекают; поэтому, если вы используете этот встроенный модуль, убедитесь, что вы определили возможные выбросы. –

+1

Даже лучше использовать '__builtin_expect' было бы использовать' -fprofile-generate' и '-fprofile-use', чтобы позволить профилировщику выяснить, какая ветвь должна быть оптимизирована [gcc options] (http://gcc.gnu.org /onlinedocs/gcc/Optimize-Options.html). Это должно вывести человеческую ошибку из уравнения и не будет вводить непереносимый код. Суть в том, что недостаточное профилирование приведет к неоптимальному коду. – user2079303

4

Side Примечание: если у вас есть код, как

if (p) a = 20; else a = 10; 

тогда нет никакой ветви. Компилятор использует условный ход (см.: Why is a conditional move not vulnerable for Branch Prediction Failure?)

+0

Я надеялся, что было ясно, что речь идет не обо всех мелких деталях, которые можно использовать, чтобы избежать ветвей. Вопрос не в 'p? 10: 20 - это просто пример. Я сделаю редактирование, чтобы сделать это явным. – porgarmingduod

+0

Вот почему я сказал, что пост был «побочным примечанием». Извините, если несколько человек считают это ответом. – hivert

+2

@hivert Возможно, это потому, что вы опубликовали ответ. –

Смежные вопросы