Is there a compiler hint for GCC to force branch prediction to always go a certain way?

前端 未结 8 1652
日久生厌
日久生厌 2020-11-28 02:06

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

8条回答
  •  醉梦人生
    2020-11-28 02:38

    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(x) loses the context for C++11 contextual conversions.

提交回复
热议问题