c++ - 帮助编译器优化分支代码序列

标签 c++ c optimization

我的 C/C++ 代码序列包含很多 分支,像这样:

if( condition1 )
    return true;
if( condition2 )
    return true;
...
return false;

(相当于返回条件1 || 条件2 || ...;)

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

关于如何实现这一点的任何想法(最好使用 gcc)?

谢谢。

最佳答案

Evaluating each of the conditions requires several memory accesses

为什么不避免个别条件下的短路求值,而是让它发生在条件的 or-ing 中?

对内置类型使用不短路的运算符

究竟如何实现前者取决于这些条件的性质(即代码中的 condition1condition2) - 鉴于您对它们一无所知,我只能谈谈一般而言:它们内部包含短路运算符,而是将 bool 值转换为整数表示并使用例如按位或(如果读起来更好并且适用于您的特定用途,甚至是“+”或“*”)。位运算符通常更安全,因为它们的优先级较低 - 仅当您的条件已经包含位运算符时才需要小心。

举例说明:

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 的隐式转换也要小心...您希望将它们规范化为 bool 以便它们的最低有效位反射(reflect)它们的 bool 意义:

OLD: return my_int && my_point && !my_double;
NEW: return bool(my_int) & bool(my_point) & !my_double;  // ! normalises before bitwise-&

您可能还想使用...进行基准测试

     bool condition1 = a > 4 & b == 2 & c < a;
     bool condition2 = a == 3 & b != 2 & c == -a;
     return condition1 || condition2;

...这可能更快 - 可能仅在整体“返回 false”的情况下,并且可能当最后一个条件 N 或两个是“返回 true”的决定因素时。

用户定义的运算符避免短路评估

另外,对具有重载逻辑运算符的对象禁用短路评估,这为您使用现有符号进行检查提供了另一种途径,但您必须更改或增强您的数据类型。

想法

更一般地说,如果您在每个单独的条件中组合了大量的断言,您只会从中受益 - 如果函数倾向于运行并返回 false,则更是如此。

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

关于c++ - 帮助编译器优化分支代码序列,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6290184/

相关文章:

arrays - 使用数组和指针的龟兔赛跑

c - 使用 * 制作循环

c++ - 使编译器/优化器能够制作更快的程序的编码实践

python - P4Python p4.temp_client 坏了?

c - 使用 C 中的 POW 函数反转五位数字

multithreading - 并行化: pthreads or OpenMP?

c# - 如何最大限度地提高 C# 中大数组的按元素操作的性能

c++ - 如何获取 C++ 中抽象(?)pimpl 的调试信息?

c++ - 链接到使用 cygwin 在 Ubuntu 中编译的 .o 文件

c++ - 在简单的 pthread 中运行服务器