如何建议GCC编译器更可能的分支

10

例子:

if (almost_always_false_condition) {
       // do something
}

有没有一种方法可以建议编译器,在99%的条件下将为false。 条件计算需要大约60个周期进行检查,并且编译器本身无法在编译时计算它。

(gcc 4.3)


相关:https://dev59.com/ynI-5IYBdhLWcg3wy72n - David Cary
5个回答

10
如果你想向GCC建议一个条件很可能具有特定值,并提示他们安排代码流程,你应该使用__builtin_expect( )
if (__builtin_expect(almost_always_false_condition,0)) {
   // do something
}

然而,听起来你想找到一种避免评估条件的方法,但是__builtin_expect()不会做到这一点。你是否有一种快速近似条件的方法,并且只在近似条件为真时进行完整检查:

if (__builtin_expect(fastCheckThatIsTrueIfFullConditionIsTrue,0)) {
    // most of the time, we don't even get to here, so you don't need
    // to evaluate the condition
    if (almostAlwaysFalseCondition) {
        // do something
    }
}

你能告诉我们更多关于这种情况的信息吗?


感谢您提供这个提示和示例。 该条件用于记录日志,如果需要,可以打开。该值在编译时未知(我们不能有两个启用和禁用日志记录的二进制版本),在可能的情况下已经进行了“快速检查”。 - Karol
__builltin_expect如何改变代码流程以使其更有效?是否有一种可移植的方法来为没有等效扩展的编译器做到这一点? - greatwolf
@Victor T.:不,没有可移植的方法来做到这一点。 - Stephen Canon

3
如果结果在单次运行中可能会有所不同,您可以使用布尔运算符的惰性求值来将条件分成廉价部分和昂贵部分,并先运行廉价部分。
if (a == 5 && somethingexpensive())
{
   ...
}

由于计算a == 5somethingexpensive()更便宜,如果它几乎总是false,则应该首先运行它,这可以避免评估somethingexpensive子句。

另一方面,如果结果在程序运行期间保持不变,则可以通过将计算结果存储在静态或全局变量中来进行优化。

static int result = doevalfunctiononlyonce();

if (result)
{
   ....    
}

这样,您就将if的成本降低到了一个简单的内存查找。
如果条件仅在响应另一个过程中的操作而更改,则可以从该过程更新全局变量:
int condition;

void appendToList(int a)
{
   list.append(a);
   if (list.somethingexpensive())
   {
     condition = true;
   } else
   {
     condition = false;
   }
}

void someotherfunction()
{
  // if (list.somethingexpensive())
  if (condition)
  {
    ...
  }
}

如果someotherfunction被调用的次数比appendtolist函数多得多,那么这将非常有用。


2
首先,你需要知道在else子句或程序的其他位置花费了多少个循环周期?如果你进行分析或获取stackshots,那么你是否在该测试中花费了至少10%的时间?如果没有,那么可能存在更大的问题,你应该首先关注这些问题。
其次,如果你在该测试中花费了>10%的时间,你应该查看算法是否可以调整,使决策点更接近50-50的概率。当执行50-50的决策点时,会产生1位信息,而99-1的决策点只产生约0.07位信息*(即它不会告诉你太多信息,因此它是CPU周期的低效使用)。这种现象的一个例子是将线性搜索与二分搜索进行比较。
*如果你有一个二元决策点,并且结果的概率分别为ab,则信息量(熵)以位为单位为-(a*log(a) + b*log(b))/log(2)

0

0
文档建议gcc可以执行基于概要文件的优化。我从未尝试过使用gcc进行此操作,因此无法提供更多建议,您可以尝试在谷歌上搜索。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接