Лучшее ожидание от C++ вероятно
В соответствии с C++
предсказание с учетом ветвлений, я подготовил тест, чтобы увидеть, насколько он эффективен.
Итак, в контрольном образце я пишу:
int count=0;
for (auto _ : state) {
if(count%13==0) {
count+=2;
}
else
count++;
benchmark::DoNotOptimize(count);
}
В C++11
прогноз-ветвь, я пишу:
#define LIKELY(condition) __builtin_expect(static_cast<bool>(condition), 1)
#define UNLIKELY(condition) __builtin_expect(static_cast<bool>(condition), 0)
int count=0;
for (auto _ : state) {
if(UNLIKELY(count%13==0)) {
count+=2;
}
else
count++;
benchmark::DoNotOptimize(count);
}
В C++20
,
int count=0;
for (auto _ : state) {
if(count%13==0)[[unlikely]]{
count+=2;
}
else
count++;
benchmark::DoNotOptimize(count);
}
который, к сожалению, не поддерживается в quick-bench
, Но в любом случае я оставляю это там.
Теперь получение эталонного теста под gcc и clang не показывает эффективности для такого базового примера.
Я делаю что-то не так?
2 ответа
Ваш стенд не показывает разницы, потому что предсказание ветвления ЦП так же хорошо, как gcc __builtin_expect
оптимизировать ваш тривиальный пример.
Полное подробное объяснение того, что такое предсказание ветвления, смотрите в этом превосходном ответе о переполнении стека.
Ваши три теста одинаковы.
В первом примере компилятор угадывает, какой путь горячий, он угадывает второй, и он уходит.
Во втором примере вы сообщаете компилятору, что второй путь горячий, поэтому результат совпадает с первым.
Я перезапустил тесты, явно указав вероятную и маловероятную ветвь, ниже приводится результат использования Clang.
http://quick-bench.com/-GZXTQk6hvKxm19s8FzgyzgHO0I
Запуск этого теста в GCC 8.2 все еще не показывает разницы, я полагаю, потому что он полностью оптимизирует ветви.