【发布时间】:2012-02-09 03:25:19
【问题描述】:
我编写了这个简单的 C 程序:
int main() {
int i;
int count = 0;
for(i = 0; i < 2000000000; i++){
count = count + 1;
}
}
我想看看gcc编译器如何优化这个循环(显然添加1 2000000000次应该是“添加2000000000一次”)。所以:
gcc test.c 然后time a.out 给出:
real 0m7.717s
user 0m7.710s
sys 0m0.000s
$ gcc -O2 test.c 然后time ona.out` 给出:
real 0m0.003s
user 0m0.000s
sys 0m0.000s
然后我用gcc -S 反汇编了两者。第一个似乎很清楚:
.file "test.c"
.text
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
pushq %rbp
.cfi_def_cfa_offset 16
movq %rsp, %rbp
.cfi_offset 6, -16
.cfi_def_cfa_register 6
movl $0, -8(%rbp)
movl $0, -4(%rbp)
jmp .L2
.L3:
addl $1, -8(%rbp)
addl $1, -4(%rbp)
.L2:
cmpl $1999999999, -4(%rbp)
jle .L3
leave
.cfi_def_cfa 7, 8
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
.section .note.GNU-stack,"",@progbits
L3 相加,L2 比较 -4(%rbp) 和 1999999999,如果 i < 2000000000 则循环到 L3。
现在优化了:
.file "test.c"
.text
.p2align 4,,15
.globl main
.type main, @function
main:
.LFB0:
.cfi_startproc
rep
ret
.cfi_endproc
.LFE0:
.size main, .-main
.ident "GCC: (Ubuntu/Linaro 4.5.2-8ubuntu4) 4.5.2"
.section .note.GNU-stack,"",@progbits
我完全不明白那里发生了什么!我对组装知之甚少,但我期待类似的东西
addl $2000000000, -8(%rbp)
我什至尝试使用 gcc -c -g -Wa,-a,-ad -O2 test.c 来查看 C 代码及其转换为的程序集,但结果是没有更清楚,前一个。
谁能简单解释一下:
- gcc -S -O2 输出。
- 如果循环按照我的预期优化(一个总和而不是多个总和)?
【问题讨论】:
-
好问题顺便说一句,欢迎来到 Stackoverflow!这是一个很好的第一个问题的好例子。 :)
标签: c gcc compiler-optimization disassembly