Руководство по использованию __builtin_expect
Что я должен обернуть с GCC __builtin_expected
макросы в пределах 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)))))
Я надеюсь, что это просто излишество, потому что это почти невозможно прочитать.
1 ответ
Я не думаю, что здесь есть неправильный ответ. Компилятор будет использовать ваши подсказки, чтобы решить, в каком случае делать случай "другого" при каждом сравнении; это не только код на C, но также и в ands и ors логики, и чем больше информации, тем лучше.
Ради читабельного кода я бы рекомендовал сохранить его в большом материале: один раз для каждого оператора if, но на самом деле это не основано на каких-либо веских доказательствах.
Рассматривали ли вы использование -fprofile-generate
, запустите код с типичными данными, а затем пересоберите с -fprofile-use
? Таким образом, компилятор может построить свою собственную картинку для всех этих случаев. Это более переносимо (без специфических для компилятора аннотаций), более читабельно и более перспективно на будущее.