【问题标题】:Does the c++ compiler combine multiple algorithms into one loop?c++编译器是否将多种算法组合成一个循环?
【发布时间】:2013-04-07 11:47:46
【问题描述】:

假设我们有以下代码:

int main () {
 int myints[] = {3,7,2,5,6,4,9};

 // using default comparison:
 std::cout << "The smallest element is " << *std::min_element(myints,myints+7) << '\n';
 std::cout << "The largest element is "  << *std::max_element(myints,myints+7) << '\n';
}

编译器会将上述优化为一个循环吗?还是写在一个for循环中更好?

【问题讨论】:

  • 这听起来像是一个微优化问题...
  • 没有像 the C++ 编译器这样的东西。有你的 C++ 编译器,还有我的 C++ 编译器。你的可能没有优化,我的可能。告诉编译器的唯一方法是检查编译器生成的代码。我同意 Oli 的观点,你应该担心的不是这个。
  • 有可能。从理论上讲,它还可以用指令的矢量化版本替换这两个调用,因此“for”循环看起来会非常不同。如果单个循环对您很重要,您应该自己编写。

标签: c++ c++11 compiler-optimization


【解决方案1】:

这取决于编译器。例如,我的编译器(x86_64 上的g++ 4.7.3)没有,保留两个单独的循环(使用-O3 编译时):

_main:
;=== initialization code omitted ===
        jmp     L2
L3:
        movl    (%rax), %edx
        cmpl    %edx, %ebx
        cmovg   %edx, %ebx
L2:
        addq    $4, %rax
        cmpq    %rbp, %rax
        jne     L3
;=== output code omitted ===
        jmp     L8
L6:
        movl    (%rax), %ecx
        cmpl    %ecx, (%rdx)
        cmovl   %rax, %rdx
L8:
        addq    $4, %rax
        cmpq    %rbp, %rax
        jne     L6
;=== output code omitted ===

【讨论】:

    【解决方案2】:

    根据定义,优化不是标准强制要求的,因此它实际上取决于编译器......以及其他条件的提升。

    不过,在您的特殊情况下,我想发信号 std::minmax_element... 可能会派上用场。

    【讨论】:

    • 我投反对票是因为标准的迂腐主义≠编译器,虽然正确且有用,但只是对实际问题的旁注。对于您的第二条评论,这一点具有双重意义。
    【解决方案3】:

    答案在很多方面都是一样的,这取决于。

    ,如果编译器决定将循环融合在一起,因为它将基于启发式方法适当地提高运行时性能。

    No 更合适,因为只有 7 个元素,loop-fusion 没有意义。

    还请注意,融合没有意义,因为该操作仅执行一次(在该示例中)。


    要获得更详细的答案,请查看编译器的汇编输出并比较不同编译器的输出。


    另一件事是,如果不能提高性能,为什么还要关心这种微优化。

    【讨论】:

    • 感谢您的回复!我实际上有更大的向量,以及 12 个单独的 std::transform 和 c++11 中的 lambda 函数。
    • 我投了反对票,因为您的回答是“如果编译器进行循环融合,编译器会进行循环融合,而且它也可能不会......也不进行微优化。”这听起来非常像是一种轻蔑的重言式,而不是一个明智的答案。
    • @Veedrac 我是否应该列出所有可能的当前和未来编译器以及所有标志...确保答案不清楚,但可以将其框定为“取决于编译器可能进行的优化和设置”
    猜你喜欢
    • 1970-01-01
    • 2013-10-03
    • 2011-03-28
    • 1970-01-01
    • 2019-08-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-10
    相关资源
    最近更新 更多