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
ifandelsebranch withlikelygets a warning (unlikelythe 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_unpredictablebut 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: