【问题标题】:C++ Branch Prediction HintsC++ 分支预测提示
【发布时间】:2020-12-16 23:22:25
【问题描述】:

考虑两个等效函数

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

显然,编译器无法确定哪种情况更有可能——但我提前知道。

我觉得我应该以后一种形式构建我的代码,因为它支持我所知道的分支预测。

问题是这会变得很难看

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

    // foo code
}

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

是否有一个关键字可以让编译器知道哪些情况更有可能(可能取决于编译器)? 如果不是,编译器在优化分支预测代码时是否考虑了这些健全性检查情况? 我应该习惯金字塔形的后一种代码吗?

为了这个问题,只考虑最流行的编译器,如 MSVC、GCC、clang 等。

【问题讨论】:

  • 由于短路规则,最后一个相当于if(check[0] && check[1] && check[2]) { /* foo code */ }。我希望这两种形式都能编译成相同的代码,至少在启用优化时是这样。然而,这与可能性问题是正交的。
  • @dxiv 我故意将它们分开,因为通常健全性检查不是您可以在if() 中准备的东西。您必须调用几个函数,然后再决定。
  • @IgorTandetnik 是的,这是 GCC 并且与问题相关。也就是说,这个问题很老,我认为 c++ 现在添加了一个关键字
  • 对引用问题的第二个回答提到了 C++20 [[likely]][[unlikely]] 属性。

标签: c++ gcc visual-c++ clang c++17


【解决方案1】:

是的,使用__builtin_expect内置函数,查看更多信息here

无论如何,作为一般规则,首先编写最可能的if 分支,它们将在之前执行(例如switch 块可能不是这样)。

【讨论】:

  • 您能否评论一下其他编译器,例如 MSVC?
猜你喜欢
  • 2018-06-15
  • 2011-04-11
  • 2014-07-17
  • 2012-02-11
  • 2014-04-25
  • 2014-03-03
  • 2016-07-01
  • 2011-02-01
相关资源
最近更新 更多