tôi đã viết này chương trình C đơn giản:Làm thế nào để GCC tối ưu hóa một biến không sử dụng được tăng lên bên trong một vòng lặp?
int main() {
int i;
int count = 0;
for(i = 0; i < 2000000000; i++){
count = count + 1;
}
}
tôi muốn tìm hiểu xem trình biên dịch gcc tối ưu hóa vòng lặp này (thêm rõ ràng 2000000000 lần nên "thêm một thời gian"). Vì vậy:
gcc test.c và sau đó time
trên a.out
cho:
real 0m7.717s
user 0m7.710s
sys 0m0.000s
$ gcc -O2 test.c và sau đó time on
a.out` cho:
real 0m0.003s
user 0m0.000s
sys 0m0.000s
Sau đó, tôi đã tháo rời cả hai với gcc -S
. Người đầu tiên có vẻ khá rõ ràng:
.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 thêm, L2 so sánh -4(%rbp)
với 1999999999
và vòng để L3 nếu i < 2000000000
.
Bây giờ tối ưu hóa một:
.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
Tôi không thể hiểu tại tất cả những gì đang diễn ra ở đó! Tôi đã có chút kiến thức về lắp ráp, nhưng tôi mong đợi một cái gì đó giống như
addl $2000000000, -8(%rbp)
Tôi thậm chí đã cố gắng với gcc -c -g -Wa, -a, -ad -O2 test.c để xem mã C cùng với việc lắp ráp nó đã được chuyển đổi thành, nhưng kết quả là không rõ ràng hơn rằng trước đó.
Ai đó có thể giải thích ngắn gọn:
- Các gcc -S -O2 đầu ra.
- Nếu vòng lặp được tối ưu hóa như tôi mong đợi (một tổng thay vì nhiều khoản tiền)?
Câu hỏi hay về btw và chào mừng bạn đến với Stackoverflow! Đây là một ví dụ tốt về câu hỏi đầu tiên tuyệt vời để hỏi. :) – Mysticial