For the Intel architectures, is there a way to instruct the GCC compiler to generate code that always forces branch prediction a particular way in my code? Does the Intel h
The correct way to define likely/unlikely macros in C++11 is the following:
#define LIKELY(condition) __builtin_expect(static_cast(condition), 1)
#define UNLIKELY(condition) __builtin_expect(static_cast(condition), 0)
This method is compatible with all C++ versions, unlike [[likely]]
, but relies on non-standard extension __builtin_expect
.
When these macros defined this way:
#define LIKELY(condition) __builtin_expect(!!(condition), 1)
That may change the meaning of if
statements and break the code. Consider the following code:
#include
struct A
{
explicit operator bool() const { return true; }
operator int() const { return 0; }
};
#define LIKELY(condition) __builtin_expect((condition), 1)
int main() {
A a;
if(a)
std::cout << "if(a) is true\n";
if(LIKELY(a))
std::cout << "if(LIKELY(a)) is true\n";
else
std::cout << "if(LIKELY(a)) is false\n";
}
And its output:
if(a) is true
if(LIKELY(a)) is false
As you can see, the definition of LIKELY using !!
as a cast to bool
breaks the semantics of if
.
The point here is not that operator int()
and operator bool()
should be related. Which is good practice.
Rather that using !!(x)
instead of static_cast
loses the context for C++11 contextual conversions.