1

Consider the two equivalent functions

void foo( )
{
    if( unlikely_case )
        return;
    
    // foo code
}
void foo( )
{
    if( !unlikely_case )
    {
        // foo code
    }
}

Obviously, the compiler can't decide which case is more likely -- but I know ahead of time.

I feel that I should structure my code in the latter form since it is supports what I know of branch prediction.

The issue is this can get ugly

void foo( )
{
    if( !sanity_check[ 0 ] )
        return;
    if( !sanity_check[ 1 ] )
        return;
    if( !sanity_check[ 2 ] )
        return;

    // foo code
}

vs

void foo( )
{
    if( sanity_check[ 0 ] )
        if( sanity_check[ 1 ] )
            if( sanity_check[ 2 ] )
            {
                // foo code
            }
}

Is there a keyword I can use to let the compiler know which cases are more likely (probably compiler dependant)? If not, are these sanity-check situations something the compiler takes into consideration when optimizing code for branch prediction? Should I just get used to the pyramidal, latter code?

For the sake of the question, consider only the most popular compilers like MSVC, GCC, clang, etc.

j__
  • 632
  • 4
  • 18
  • 1
    Likely relevant: [How do the likely/unlikely macros in the Linux kernel work and what is their benefit?](https://stackoverflow.com/questions/109710/how-do-the-likely-unlikely-macros-in-the-linux-kernel-work-and-what-is-their-ben) – Igor Tandetnik Aug 28 '20 at 02:57
  • The last one is equivalent to `if(check[0] && check[1] && check[2]) { /* foo code */ }` due to the shortcircuit rules. I would expect both forms to compile to the same code, at least when optimizations are enabled. This is orthogonal to the question of likelihood, however. – dxiv Aug 28 '20 at 02:58
  • @dxiv I purposely separated them as usually sanity checks aren't things you can prepare within the `if()`. You must call a few functions and then decide. – j__ Aug 28 '20 at 03:00
  • @IgorTandetnik Yea that's GCC and is relevant to the question. That said, that question is old and I figured c++ added a keyword by now – j__ Aug 28 '20 at 03:01
  • 3
    Second answer to the question cited mentions C++20 `[[likely]]` and `[[unlikely]]` attributes. – Igor Tandetnik Aug 28 '20 at 03:03
  • So it's a C++ 20 feature, then... Disappointing but better late than never. – j__ Aug 28 '20 at 03:04
  • Does this answer your question? [likely/unlikely equivalent for MSVC](https://stackoverflow.com/questions/1440570/likely-unlikely-equivalent-for-msvc) – yugr Aug 28 '20 at 05:02

1 Answers1

1

Yes, use __builtin_expect built-in function, see more info here.

Anyway, as a general rule, write first the most probable if branches, they will be executed before (this might not be true with switch blocks for example).

Victor
  • 460
  • 3
  • 11