编译器如何优化这段代码

时间:2016-12-30 23:26:59

标签: c++ optimization

考虑以下循环:

unsigned long x = 0;
for(unsigned long i = 2314543142; i > 0; i-- )
    x+=i;
std::cout << x << std::endl;

当我正常编译时,执行此循环大约需要6.5秒。但是当我用-O3优化编译时,循环在10 ^ -6秒内执行。这怎么可能?编译器肯定不知道x ...的封闭表单表达式如何...

2 个答案:

答案 0 :(得分:4)

如果使用优化进行编译,你不必真正了解程序集的所有内容,以确定编译器在编译时确定x的值。

我稍微修改了您的代码,以便能够使用在线工具Compiler Explorer,将std::cout << x << std::endl更改为extern unsigned long foo;foo = x;。没有必要,但它使输出更清洁。

使用-O2编译:

test():
        movabs  rax, 2678554979246887653
        mov     QWORD PTR foo[rip], rax
        ret

使用-O0编译:

test():
        push    rbp
        mov     rbp, rsp
        mov     QWORD PTR [rbp-8], 0
        mov     DWORD PTR [rbp-16], -1980424154
        mov     DWORD PTR [rbp-12], 0
        jmp     .L2
.L3:
        mov     rax, QWORD PTR [rbp-16]
        add     QWORD PTR [rbp-8], rax
        sub     QWORD PTR [rbp-16], 1
.L2:
        cmp     QWORD PTR [rbp-16], 0
        setne   al
        test    al, al
        jne     .L3
        mov     rax, QWORD PTR [rbp-8]
        mov     QWORD PTR foo[rip], rax
        leave
        ret

此外:由于i >= 0只输出了未定义行为的代码的第一个修订版:

test():
.L2:
        jmp     .L2

: - )

答案 1 :(得分:3)

编译器在循环之后确定x的值并在输出语句中使用它。