Maison >développement back-end >C++ >Les compilateurs C/C modernes utilisent-ils des instructions Push/Pop pour une gestion efficace des variables locales ?

Les compilateurs C/C modernes utilisent-ils des instructions Push/Pop pour une gestion efficace des variables locales ?

Barbara Streisand
Barbara Streisandoriginal
2024-12-02 19:18:15559parcourir

Do Modern C/C   Compilers Utilize Push/Pop Instructions for Efficient Local Variable Management?

Quels compilateurs C/C peuvent utiliser les instructions Push/Pop pour créer des variables locales ?

Introduction

Contrairement à la pratique courante consistant à augmenter progressivement l'ESP, cette question explore la possibilité d'utiliser des instructions push et pop pour établir des variables, visant à optimiser la compacité du code et éventuellement les performances.

Considérations sur le compilateur

Optimisation du compilateur :

  • Tous quatre compilateurs x86 majeurs (GCC, ICC, MSVC, clang) ont abandonné le push pour optimisations.
  • Cela est principalement dû à l'utilisation élevée du push sur les processeurs d'antan, ce qui a eu un impact négatif sur l'efficacité du cœur super-scalaire.
  • Cependant, les compilateurs modernes ont réintroduit le push/pop pour des gains de performances, en particulier dans la manipulation des arguments de la pile et des registres préservés par les appels.

Stack Engine Optimisation :

  • Les processeurs récents comme Intel depuis Pentium-M et AMD depuis Bulldozer intègrent un "moteur de pile" qui suit efficacement les modifications RSP.
  • Cette fonctionnalité permet d'utiliser push/pop/call/ret sans encourir de pénalités de performances.
  • Une utilisation prudente de push/pop peut conduire à des améliorations de performances en optimisant pour la vitesse plutôt que uniquement la taille du code.

Échantillon de code

Considérez l'exemple suivant :

int extfunc(int *, int *);

void foo() {
    int a=1, b=2;
    extfunc(&a, &b);
}

Sortie du compilateur

GCC, ICC, MSVC et clang génèrent tous du code qui commence par une instruction push, suivie de manipulation de la pile et appel à extfunc. Cela concorde avec l'observation selon laquelle les compilateurs modernes utilisent Push pour les optimisations.

Solution optimale

Une autre solution optimisée serait :

push    2                  # only 2 bytes
lea     rdi, [rsp + 4]
mov     dword ptr [rdi], 1
mov     rsi, rsp              # special case for lea rsi, [rsp + 0]
call    extfunc(int*, int*)
pop     rax                 # alternative to add rsp,8
ret

Dans dans ce cas, une seule instruction push alloue de l'espace pour les deux variables locales tout en laissant la pile alignée sur 16 octets. Cela optimise la taille du code et maintient l'efficacité.

Considérations supplémentaires

  • Le mélange des modes d'adressage push avec [rsp] peut introduire des uops de synchronisation de pile supplémentaires sur les processeurs Intel, réduisant potentiellement l'efficacité.
  • Les compilateurs s'abstiennent généralement de mettre en œuvre cette optimisation car elle nécessite un calcul minutieux et un équilibrage des compromis pour éviter les performances dégradation.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn