There are [[likely]]
and [[unlikely]]
attributes in modern C++. There are corresponding __builtin_expect(x, 1)
and __builtin_expect(x, 0)
builtins in G++ and clang++. But also there are __builtin_unpredictable(x)
and __builtin_expect_with_probability(x, 1, 0.5)
or (equally) __builtin_expect_with_probability(x, 0, 0.5)
builtins, which tells compiler to prevent CPU to fill pipeline with instructions from (mis)predicted branch, because the cost of flush+recovery of the pipeline from mispredicted path is statistically greater than execution w/o speculative execution at all.
Would be the using of [[likely]]
or equally [[unlikely]]
attributes on both if
and else
branches like in following snippets an equivalent of the using of hypothetical [[unpredictable]]
attribute?
if (x) [[likely]] {
// "if" branch
} else [[likely]] {
// "else" branch
}
or
if (x) [[unlikely]] {
// "if" branch
} else [[unlikely]] {
// "else" branch
}
As I know if
branch is treated by compilers as [[likely]]
by default if there is else
, and [[unlikely]]
if there no else
(because it is often the form of unhappy path checking with early exit from the current function). So if I just omit either of attributes, then it is not equivalent to specify hypothetical [[unpredictable]]
attribute.
It seems marking both
if
andelse
branch withlikely
gets a warning (unlikely
the same):So I guess the question remains hypothetical. As for a minimal complete example, it seems
g++
supports[[likely]]
and[[unlikely]]
but not__builtin_unpredictable
. Similarly,clang++
supports__builtin_unpredictable
but not[[likely]]
nor[[unlikely]]
(at least clang 10 doesn't. So comparing all three options is tricky. Here is a minimal complete example that compares[[likely]]
versus[[unlikely]]
:And here is the evaluation: