7
votes

Le compilateur est-il autorisé à optimiser l'utilisation de la mémoire de pile en réorganisant des variables locales?

Considérez le programme suivant:

    3 bytes unused                  3 bytes unused
     vvvvvvvvvvv                     vvvvvvvvvvv
+---+---+---+---+---+---+---+---+---+---+---+---+
| a |   |   |   | i             | b |   |   |   |
+---+---+---+---+---+---+---+---+---+---+---+---+

                |
                v

+---+---+---+---+---+---+---+---+
| a | b |   |   | i             |
+---+---+---+---+---+---+---+---+
         ^^^^^^^
      2 bytes unused


7 commentaires

En supposant que cela soit autorisé par les normes, etc., il serait alors totalement à la mise en œuvre du compilateur individuel, qu'ils le font ou non. J'imagine que cela serait contrôlé par des niveaux d'optimisation lors de la compilation.


Le compilateur / optimiseur est libre de placer les locaux partout où il le souhaite, tant qu'il ne casse pas le programme. Il est libre de placer deux variables au même endroit s'il est certain qu'ils ne sont jamais utilisés en même temps.


Avez-vous essayé de compiler avec différentes options d'optimisation? Peut-être que vous avez compilé avec les optimisations.


Fais-t-il une différence si vous utilisez -Os ? Avec O3 , vous dites au compilateur d'utiliser des optimisations qui rendront le code plus grand, si cela le rend plus rapide.


Je pense que le compilateur optimise déjà l'espace mémoire. À partir du code de montage: A , B et i sera à l'adresse 26 (% ESP), 27 (% ESP) et 28 (% ESP).


Toute discussion sur l'optimisation est complètement inutile sans un système spécifique à l'esprit. J'essaie de lire l'esprit de l'opération ... Hmm ... Ceci est un système Linux ou Windows sur un dérivé Intel X86 32 bits.


@Lundin c'est Windows 64 bits sur un noyau Intel i5 avec Mingw GCC


5 Réponses :


7
votes

Le compilateur est libre de mettre en place les variables locales telles qu'il souhaite. Il n'est même pas nécessaire d'utiliser la pile.

Il peut stocker les variables locales dans une commande non liée à l'ordre de déclaration sur la pile s'il utilise la pile.

est le compilateur autorisé à effectuer cette optimisation (par la norme C etc.)?

  • Si oui, pourquoi n'est-ce pas ci-dessus?

    Eh bien, est-ce une optimisation du tout?

    Ce n'est pas clair. Il utilise un couple d'octets moins, mais cela compte rarement. Mais sur certaines architectures, il peut être plus rapide de lire un Char s'il est enregistré par mot aligné. Ainsi, mettez ensuite le Char S à côté de l'autre, obligerait l'un d'entre eux au moins à ne pas être aligné par Word et faire la lecture plus lente.


1 commentaires

Cela ne répond pas pleinement à la question. Un couple d'octets sur la pile d'appels peut compter lors de la mise en œuvre d'un algorithme récursif. C est la langue de la programmation des systèmes, permettant ainsi une mémoire si possible est une préoccupation. La question est de savoir si GCC manque une opportunité d'optimisation ou choisit un côté d'un compromis. Il est presque certainement vrai que sur Certaines architectures , il est plus rapide de lire un char d'un emplacement aligné; Mais l'assemblage est généré pour une architecture concrète. Si cette architecture n'impose pas une pénalité pour des lectures non alignées, l'optimisation manque.



0
votes

Généralement dans des systèmes normaux où la vitesse compte, le mot de lecture Wise est plus rapide que le caractère de lecture sage. La perte de mémoire par rapport au gain de vitesse est ignorée. Mais dans le cas du système où la mémoire importe, comme dans différents compilateurs de croix générant exécutable (dans une signification très générique) pour une plate-forme cible particulière, l'image peut être entièrement différente. Le compilateur peut les emballer, même vérifier leur vie et leur utilisation, en fonction de celui-ci, en fonction de la bitwidth, etc., il est donc fortement dépendant de la nécessité. Mais en général, chaque compilateur vous donne la flexibilité si vous souhaitez "pack" heridement. Vous pouvez examiner le manuel pour cela


0 commentaires

2
votes

Ce ne serait pas plus efficace de mémoire si le compilateur modifierait l'ordre des variables

Il n'y a aucun moyen de dire sans parler d'une CPU spécifique, d'un système d'exploitation spécifique et d'un compilateur spécifique. En général, le compilateur fait de manière optimale. Afin d'optimiser le code de manière significative, vous avez besoin de connaissances approfondies sur le système spécifique.

Dans votre cas, le compilateur est probablement défini pour optimiser la vitesse dans ce cas. Il semble que le compilateur ait décidé que les adresses alignées pour chaque variable donnent le code le plus efficace. Sur certains systèmes, il n'est pas seulement plus rapide, mais également obligatoire d'allouer à des adresses égales, car certains processeurs ne peuvent gérer que l'accès aligné.

est le compilateur autorisé à effectuer cette optimisation (par la norme C etc.)?

Oui, la norme C n'exige même pas que les variables soient allouées. Le compilateur est totalement libre de gérer cela de quelque manière que ce soit, il souhaite et il n'a pas besoin de documenter comment ou pourquoi. Il peut allouer les variables n'importe où, cela pourrait les optimiser entièrement ou les allouer à l'intérieur des registres du processeur ou sur la pile, ou dans une petite boîte en bois sous votre bureau.


0 commentaires

0
votes

compilateurs avec tampon Protection de débordement de la pile ( / gs pour Microsoft's Compiler) peut réorganiser des variables comme une fonctionnalité de sécurité. Par exemple, si vos variables locales sont une matrice de grincement de taille constante (tampon) et un pointeur de fonction, un attaquant qui peut déborder le tampon pourrait également écraser le pointeur de fonction. Ainsi, les variables locales sont réorganisées de manière à ce que le tampon soit à côté du canari. De cette façon, un attaquant ne peut (directement) compromettre le pointeur de la fonction et le débordement tampon est (espérons-le) détecté par le canaris détruit.

AVERTISSEMENT: De telles fonctionnalités n'empêchent pas de compromis, ils ne font que lever les barrières d'un attaquant, mais un attaquant qualifié trouve normalement son chemin.


0 commentaires

4
votes

est le compilateur autorisé à effectuer cette optimisation (par la norme C etc.)?

oui.

Si oui, pourquoi cela ne va-t-il pas ci-dessus?

C'est arrivé.

Lisez attentivement la sortie de l'assembleur soigneusement. xxx

variable A est à offset 26. Variable B est décalé 27. Variable i est au décalage 28.

Utilisation des images que vous avez apportées La mise en page est maintenant la suivante: xxx


2 commentaires

Je n'ai vraiment pas remarqué le numéro dans le deuxième argument de la commande MOV (L | B)>. <, Merci pour cela. Eh bien, toujours drôle pourquoi GCC organise ces commandes dans cet ordre, il aurait été plus facile de noter s'il était l'inverse.


Aucune idée de la façon dont les instructions sont commandées de cette façon. Si je devais spéculer soit, c'est quelque chose à propos de deux instructions movb touchant le même mot de mémoire qui pourrait étaller (bien que nous ayons des tampons de stockage pour une raison, il est donc peu probable) ou plus susceptible de: T Peu importe, ils ont donc été générés dans l'ordre que le compilateur les a euts dans l'arbre de syntaxe interne.