8
votes

Un exemple d'optimisation impliquant une réorganisation du compilateur

Les compilateurs C & C ++ sont autorisés à réorganiser des opérations aussi longtemps que le as-si règle détient. Quel est un exemple d'une telle réorganisation effectuée par un compilateur et quel est le gain de performance potentiel à faire en le faisant?

Exemples impliquant tout compilateur (C / C ++) sur n'importe quelle plate-forme sont les bienvenus.


3 commentaires

Avez-vous vu presht.com/20120625/memory-ordering-at-compile- Temps ?


@NPE J'ai démontré le premier exemple de travail à l'aide de Godbolt ici


J'ai vu cet article, entre autres, mais je ne pouvais pas trouver une explication quant à la raison pour laquelle le compilateur a motivé qu'un tel ordonnance pourrait potentiellement améliorer les performances.


3 Réponses :


4
votes

Je suis sûr qu'il y a plusieurs exemples où les opérations de réorganisation produiront des performances plus rapides. Un exemple évident serait de réorganiser des charges le plus tôt possible, car ceux-ci sont généralement beaucoup plus lents que les autres opérations de la CPU. En faisant d'autres travaux non liés tandis que la mémoire est récupérée, la CPU peut gagner du temps dans l'ensemble.

C'est-à-dire, étant donné quelque chose comme ceci: P>

x = load();
expensive_calculation();
do_something(x);


0 commentaires

10
votes

Supposons que les opérations suivantes soient effectuées: xxx

ignorer pour le moment que les trois incréments seraient probablement optimisés par le compilateur dans un + = 3 , vous finirez par avoir un débit de processeur supérieur-pipeline si vous avez réorganisé les opérations comme xxx

car j ++ ne doit pas attendre Le résultat de i ++ dans le cas précédent, la plupart des instructions avaient une dépendance de données sur l'instruction précédente. Dans des calculs plus compliqués, où il n'ya pas de moyen facile de réduire le nombre d'instructions à effectuer, le compilateur peut toujours regarder les dépendances de données et la réorganisation des instructions de manière à ce qu'une instruction en fonction du résultat d'une instruction antérieure soit aussi loin. de l'heure que possible.

Un autre exemple d'une telle optimisation est lorsque vous traitez avec pure Fonctions . En regardant à nouveau un exemple simple, supposez que vous avez une fonction pure f (int x) que vous ressemblez sur une boucle. xxx

depuis < Code> F est une fonction pure, le compilateur peut la réorganiser les appels comme il leur plaît. En particulier, il peut transformer cette boucle sur xxx


0 commentaires

4
votes

Supposons que vous ayez une boucle comme: xxx

pense memcpy . Vous voudrez peut-être que le compilateur puisse viller à vous viller à cela, c'est-à-dire charger 8 ou 16 octets à la fois, puis stocker 8 ou 16 à la fois. Rendre cette transformation est une réorganisation, car elle causerait src [1] à lire avant DEST [0] est stocké. De plus, à moins que le compilateur sait que src et doss ne se chevauchent pas, c'est une transformation non valide , c'est-à-dire un compilateur n'est pas autorisé à faire . Utilisation du mot clé restreindre (C99 et version ultérieure) vous permet de dire au compilateur qu'ils ne se chevauchent pas pour que ce type d'optimisation (extrêmement précieux) soit possible.

Le Le même genre de chose se pose tout le temps dans les opérations sur des tableaux qui ne sont pas simplement copier - des choses comme des opérations de vecteur / matriciel, des transformations de données d'échantillons son / image, etc.


0 commentaires