escribí este sencillo programa C:¿Cómo optimiza GCC una variable no utilizada que se incrementa dentro de un ciclo?
int main() {
int i;
int count = 0;
for(i = 0; i < 2000000000; i++){
count = count + 1;
}
}
quería ver cómo el compilador gcc optimiza este bucle (añadir claridad 1 2000000000 tiempos deben ser "agregan una vez"). Por lo tanto:
gcc test.c y luego en time
a.out
da:
real 0m7.717s
user 0m7.710s
sys 0m0.000s
$ gcc -O2 test.c y luego time on
a.out` da:
real 0m0.003s
user 0m0.000s
sys 0m0.000s
Luego desarmé ambos con gcc -S
. El primero parece bastante claro:
.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 añade, L2 comparar con -4(%rbp)
1999999999
y loops a L3 si i < 2000000000
.
Ahora el uno optimizado:
.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
No puedo entender en absoluto lo que está pasando allí! Tengo poco conocimiento de montaje, pero me esperaba algo así como
addl $2000000000, -8(%rbp)
Incluso probé con gcc -c -g -Wa, -a, -ad -O2 test.c para ver el código C junto con el conjunto al que se convirtió, pero el resultado no fue más claro que el anterior.
Puede alguien explicar brevemente:
- El gcc -S salida O2.
- Si el bucle está optimizado como esperaba (¿una suma en lugar de muchas sumas)?
¡Buena pregunta por cierto, y bienvenido a Stackoverflow! Este es un buen ejemplo de una excelente primera pregunta para hacer. :) – Mysticial