考虑以下循环:
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 ...的封闭表单表达式如何...
答案 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的值并在输出语句中使用它。