繁体   English   中英

GNU编译器优化

[英]GNU Compiler optimization

我对编译器知之甚少,但知道它们很复杂,足够聪明,可以优化代码。 假设我的代码看起来像这样:

 string foo = "bar";
 for(int i = 0; i < foo.length(); i++){
     //some code that does not modify the length of foo
 }

GNU编译器是否足够聪明,可以意识到foo的长度在这个循环的过程中没有改变,并用适当的值替换foo.length()调用? 或将foo.length()被调用每一个i比较呢?

由于Mysticial和Kerrek都正确地建议在生成的程序集中窥视,这里有一个例子:

#include <string>
using namespace std;

int does_clang_love_me(string foo) {
    int j = 0;
    for (int i = 0; i < foo.length(); i++) {
        j++;
    }
    return j;
}

我在test.cpp中保存了上面的代码并将其编译为:

$ clang++ -o test.o -Os -c test.cpp

-Os开关告诉clang尝试针对最小的代码大小进行优化。 GCC有一个你可以使用的相应开关。 为了查看程序集,我用otool命中了生成的目标文件,因为我此刻碰巧正在使用mac。 其他平台也有类似的工具。

$ otool -tv test.o

test.o:
(__TEXT,__text) section
__Z16does_clang_love_meSs:
0000000000000000    pushq   %rbp
0000000000000001    movq    %rsp,%rbp
0000000000000004    movq    (%rdi),%rax
0000000000000007    movq    0xe8(%rax),%rcx
000000000000000b    xorl    %eax,%eax
000000000000000d    testq   %rcx,%rcx
0000000000000010    je  0x0000001e
0000000000000012    cmpq    $0x01,%rcx
0000000000000016    movl    $0x00000001,%eax
000000000000001b    cmoval  %ecx,%eax
000000000000001e    popq    %rbp
000000000000001f    ret

就像Mysticial说的那样; 它只是一个可变访问。

确切知道的唯一方法是尝试并看看装配。

我的猜测是,如果对length()的调用是内联的,那么Loop Invariant Code Motion将把length()的内部提升出循环并用单个变量替换它。

作为第二个想法,这甚至可能没有实际意义。 字符串的大小可能只是string类中的一个简单字段 - 它位于堆栈中。 因此,只需调用length()就可以减少对简单变量访问的调用。

编辑:在后一种情况下,在循环内是否修改了foo的长度甚至都不重要。 获取字符串的长度只是一个变量访问。

编译器必须保证程序的行为就像在每一轮中调用length() 如果它可以证明没有副作用并且结果确实是恒定的,它只能将呼叫提升出循环。

在一个真实的例子中发生的事情需要逐个分析。 如果你好奇的话,看看大会吧。

强制提升的典型方法是手动执行:

for (unsigned int i = 0, end = s.length(); i != end; ++i)

也许你也想把现代for (char & c : s)作为另一种选择。

老实说,我不知道gcc将如何优化此代码段。 但是在循环外部移动冗余代码称为“部分冗余消除”。 在循环外移动foo.length(),称为循环不变代码运动,是部分冗余消除的一种形式。 请看一下龙书第9.5节(我也在阅读本章),它详细阐述了如何使用数据流分析来解决这些问题。 这是斯坦福大学的一张幻灯片: http//suif.stanford.edu/~courses/cs243/lectures/l5.pdf 希望这些会有所帮助。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM