Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/unity3d/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 帮助编译器优化branchy代码序列_C++_C_Optimization - Fatal编程技术网

C++ 帮助编译器优化branchy代码序列

C++ 帮助编译器优化branchy代码序列,c++,c,optimization,C++,C,Optimization,我有C/C++中的代码序列,其中包含许多 分支,类似这样的: if( condition1 ) return true; if( condition2 ) return true; ... return false; (相当于返回条件1 | |条件2 | |…) 评估每个条件都需要多次内存访问(均为只读),但编译器在评估前一个条件之前不移动内存访问,从而错过了重要的优化机会。原因是当condition1为true时,condition2的内存访问可能会出错。 我知道他们没有,我

我有C/C++中的代码序列,其中包含许多 分支,类似这样的:

if( condition1 )
    return true;
if( condition2 )
    return true;
...
return false;
(相当于返回条件1 | |条件2 | |…)

评估每个条件都需要多次内存访问(均为只读),但编译器在评估前一个条件之前不移动内存访问,从而错过了重要的优化机会。原因是当condition1为true时,condition2的内存访问可能会出错。 我知道他们没有,我希望编译器做一些明智的事情,在适合性能的地方混合一些代码序列,例如利用指令级并行性。 我也不想将条件更改为逻辑or(而不是短路),因为其中一个分支可能会跳出

关于如何实现这一点有什么想法(最好使用gcc)

谢谢

评估每个条件都需要多次内存访问

为什么不在个别情况下避免短路评估,但在其他情况下让短路评估发生

对内置类型使用不短路的运算符 具体实现前者的方式取决于这些条件的性质(即代码中的
condition1
condition2
)——如果您没有说明它们,我只能笼统地说:它们内部包含短路运算符,相反,将布尔值转换为整数表示形式,并使用例如按位或(如果它读起来更好并且在您的特定用法中工作,甚至使用“+”或“*”)。位运算符通常更安全,因为它们的优先级较低-只有在您的条件已经包含位运算符时才需要小心

举例说明:

OLD: return (a > 4 && b == 2 && c < a) ||   // condition1
            (a == 3 && b != 2 && c == -a);  // condition2

NEW: return (a > 4 & b == 2 & c < a) ||
            (a == 3 & b != 2 & c == -a);
您可能还希望使用

     bool condition1 = a > 4 & b == 2 & c < a;
     bool condition2 = a == 3 & b != 2 & c == -a;
     return condition1 || condition2;
bool条件1=a>4&b==2&c
…这可能更快-可能仅在整体“return false”情况下,并且可能在最后一两个条件n是“return true”的决定因素时

用户定义的操作员可避免短路评估 另外,对于具有重载逻辑运算符的对象禁用短路求值,这为您使用现有符号进行检查提供了另一种途径,但您必须更改或增强数据类型

思想 更一般地说,只有在每个条件中组合了大量断言时,您才能从中受益——如果函数倾向于运行到返回false,则更是如此


“APProgrammer”也提出了一个很好的观点——由于在现代CPU上可以进行推测性执行,CPU可能已经领先于短路评估所暗示的顺序(在某些特殊模式下,可以避免或抑制任何内存故障,从而取消对无效指针的引用、除以0等)。因此,整个优化尝试可能被证明毫无意义,甚至适得其反。需要对所有备选方案进行基准测试。

您能自己移动部分条件吗

constboolbcondition1result=;
常量布尔b条件2result=;
等等


为了更好的优化仍然。。。重新调整条件的顺序,以便首先检查命中率最高的条件。通过这种方式,它将更经常地提前退出(这可能没有什么区别)。

看看gcc提供的函数。当我们像linux内核那样定义宏时,这些宏可以直观地使用,对代码可读性几乎没有影响。

不用麻烦了。CPU已经有无序执行、推测执行和分支预测。这一级别的任何差异都不太可能产生任何影响。指令级并行是由CPU隐式完成的,而不是由编译器显式完成的。也许GCC什么也没做,因为没有什么可以得到的

在这一点上,您必须有一个地狱般的条件来改变一个非平凡应用程序的运行时间


哦,逻辑or是保证短路的标准。

也许我在这里误解了什么,但是如果(条件2)
,如果你不想在条件1为真的情况下对其进行评估,为什么不直接使用
else呢?@reko\u t:不会改变任何东西,
return
已经保证了这一点@PoweRoy:大胆的评论,这可能会使情况恶化(OO抽象并不意味着提高性能),你有事实支持吗?@PoweRoy:这会有什么帮助,确切地说?@GMan:嘿,我喜欢OOP,适度;)但在寻找性能时,这很少是一个好的答案。考虑到推测性执行的存在,我不太确定编译器是否遗漏了一些东西。你能更明确地说明条件之间的关系吗,举个例子。+1:像这样单独评估每个条件会引起条件n术语之间(但不在条件n术语内)的并行性,尽管如果优化者没有真正参与其中,它可能会导致对所有条件项的评估,即使早期的条件项足以确定函数的返回值。如果hans能给出反馈,他会很感兴趣的。
     bool condition1 = a > 4 & b == 2 & c < a;
     bool condition2 = a == 3 & b != 2 & c == -a;
     return condition1 || condition2;
 const bool bCondition1Result = <condition1>;
 const bool bCondition2Result = <condition2>;