Quand dois-je omettre le pointeur de cadre?
Est-il très optimisation lors de la omettant le pointeur de l'image?
Si j'ai bien compris en lisant cette page, -fomit-frame-pointer
est utilisé lorsque l'on veut éviter l'enregistrement, le montage et la restauration des pointeurs de frame.
Est ce fait que pour chaque appel de fonction, et si oui, est-il vraiment la peine d'éviter les quelques instructions pour chaque fonction?
N'est-il pas anodin pour une optimisation.
Quelles sont les réelles implications de l'utilisation de cette option en dehors de débogage limites?
J'ai compilé suivants du code C avec et sans cette option
int main(void)
{
int i;
i = myf(1, 2);
}
int myf(int a, int b)
{
return a + b;
}
,
# gcc -S -fomit-frame-pointer code.c -o withoutfp.s
# gcc -S code.c -o withfp.s
.
diff -u
'ing les deux fichiers ont révélé que le code assembleur:
--- withfp.s 2009-12-22 00:03:59.000000000 +0000
+++ withoutfp.s 2009-12-22 00:04:17.000000000 +0000
@@ -7,17 +7,14 @@
leal 4(%esp), %ecx
andl $-16, %esp
pushl -4(%ecx)
- pushl %ebp
- movl %esp, %ebp
pushl %ecx
- subl $36, %esp
+ subl $24, %esp
movl $2, 4(%esp)
movl $1, (%esp)
call myf
- movl %eax, -8(%ebp)
- addl $36, %esp
+ movl %eax, 20(%esp)
+ addl $24, %esp
popl %ecx
- popl %ebp
leal -4(%ecx), %esp
ret
.size main, .-main
@@ -25,11 +22,8 @@
.globl myf
.type myf, @function
myf:
- pushl %ebp
- movl %esp, %ebp
- movl 12(%ebp), %eax
- addl 8(%ebp), %eax
- popl %ebp
+ movl 8(%esp), %eax
+ addl 4(%esp), %eax
ret
.size myf, .-myf
.ident "GCC: (GNU) 4.2.1 20070719
Quelqu'un pourrait s'il vous plaît faire la lumière sur les clé points le code ci-dessus où l'option-fomit-frame-pointer n'a réellement faire la différence?
Edit: objdump
sortie de l'remplacé par gcc -S
's
- Essayez la diff de nouveau par la compilation avec -S. Comparer l'assemblée de la langue: Il sera beaucoup plus lisible.
- Fait! Merci pour tout ça!
- Connexes, voir BRAS: link register et le pointeur de l'image.
Vous devez vous connecter pour publier un commentaire.
-fomit-frame-pointer
permet un s'inscrire pour être disponible pour utilisation générale. Je suppose que ce n'est vraiment qu'une grosse affaire sur 32 bits x86, ce qui est un peu affamé de registres.*On pourrait s'attendre à voir EBP n'est plus enregistrée et réglée sur chaque appel de fonction, et probablement quelques autres l'utilisation de EBP en de code, et moins de la pile des opérations dans les occasions où EBP est utilisé comme un usage général registre.
Votre code est beaucoup trop simple pour voir aucun avantage de ce genre d'optimisation-- vous ne l'utilisez pas assez de registres. Aussi, vous n'avez pas activé l'optimiseur, qui pourrait être nécessaire pour voir certains de ces effets.
* ISA registres, pas de micro-architecture registres.
Le seul inconvénient de l'omission, c'est que le débogage est beaucoup plus difficile.
Le principal avantage est qu'il y ait un supplément de registre qui peut faire une grande différence sur la performance. Évidemment extra ce registre est utilisé uniquement lorsque cela est nécessaire (probablement dans votre fonction très simple, il n'est pas); dans certaines fonctions qu'il fait plus de différence que dans d'autres.
printf()
de débogage (qui EST toujours le débogage) est très possible, par exemple.Vous pouvez souvent obtenir plus significative de l'assemblée du code de GCC en utilisant le
-S
argument à la sortie de l'assemblée:GCC ne se soucie pas de l'adresse, afin que nous puissions comparer les instructions générées directement. Pour votre feuille de fonction, cela donne:
GCC ne génère pas le code de pousser le cadre pointeur sur la pile, et cela change l'adresse relative de la arguments passés à la fonction sur la pile.
Le profil de votre programme pour voir si il y a une différence significative.
Ensuite, le profil de votre processus de développement. Est un débogage plus facile ou plus difficile? Ne vous passez plus de temps à développer ou moins?
Optimisations sans profilage sont un gaspillage de temps et d'argent.