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? P>
Exemples impliquant tout compilateur (C / C ++) sur n'importe quelle plate-forme sont les bienvenus. P>
3 Réponses :
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);
Supposons que les opérations suivantes soient effectuées: ignorer pour le moment que les trois incréments seraient probablement optimisés par le compilateur dans un car 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 depuis < Code> F Code> 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 p> + = 3 code >, vous finirez par avoir un débit de processeur supérieur-pipeline si vous avez réorganisé les opérations comme p>
j ++ code> ne doit pas attendre Le résultat de
i ++ code> 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. p>
f (int x) code> que vous ressemblez sur une boucle. P>
Supposons que vous ayez une boucle comme: pense 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. p> p> memcpy code>. 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] code> à lire avant
DEST [0] code> est stocké. De plus, à moins que le compilateur sait que
src code> et
doss code> ne se chevauchent pas, c'est une transformation non valide em>, c'est-à-dire un compilateur n'est pas autorisé à faire . Utilisation du mot clé code> restreindre de code> (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. P>
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.