рекомендации по использованию __builtin_expect

Что мне следует обернуть макросами __builtin_expected gcc в if с несколькими и вложенными тестами? У меня есть этот код:

if((x<RADIUS && (forward?v<0:v>0)) || (x+RADIUS>dimensions[d] && (forward?v>0:v<0)))

Я (смешно) завернул все, что мог:

#define likely(x)       __builtin_expect((x),1)
#define unlikely(x)     __builtin_expect((x),0)
if(unlikely(unlikely(unlikely(x<RADIUS) && likely(likely(forward)?likely(v<0):likely(v>0))) || unlikely(unlikely(x+RADIUS>dimensions[d]) && likely(likely(forward)?likely(v>0):likely(v<0)))))

Я надеюсь, что это просто излишество, потому что это почти нечитаемо.


person Lorenzo Pistone    schedule 25.05.2012    source источник
comment
Где вы планируете запускать этот код? На практике на современных процессорах x86 предсказатели ветвлений в любом случае намного лучше, чем статические подсказки, т. Е. Если вы запускаете код достаточно часто и есть простой шаблон, они легко его подберут. Если вы недостаточно запускаете код, почему вы думаете, что несколько циклов будут иметь большое значение? Теперь, если одной из ваших целевых платформ является ARM, это, вероятно, не такая уж плохая идея.   -  person Voo    schedule 25.05.2012


Ответы (1)


Я не думаю, что здесь есть неправильный ответ. Компилятор будет использовать ваши подсказки, чтобы решить, в каком случае делать "иначе" случай каждого сравнения; это не только код C, но и внутри и и или логики, и чем больше информации, тем лучше.

Ради удобочитаемого кода я бы предложил придерживаться больших объемов: по одному разу для каждого оператора if, но на самом деле это не основано на каких-либо веских доказательствах.

Рассматривали ли вы возможность использования -fprofile-generate, запускать код с типичными данными, а затем перестраивать с помощью -fprofile-use? Таким образом, компилятор может построить свою собственную картину для всех этих случаев. Это более переносимо (без аннотаций, специфичных для компилятора), более читабельно и более перспективно.

person ams    schedule 25.05.2012