Je crée un petit programme Mesurez la différence de performance entre les conteneurs de types Le reste du code peut être trouvé ici: Main.Cpp . P> en réponse à @Neil Butterworth. Même lors de l'utilisation de la copie, il me semble toujours que le compilateur pouvait facilement éviter la copie: p> boost :: partage_ptr code> et
boost :: intrusion_ptr code>. Afin d'empêcher le compilateur d'optimiser la copie, je déclare la variable comme volatile. La boucle ressemble à ceci:
mise à jour h3>
3 Réponses :
Pourquoi devrait-il? La meilleure solution consiste à utiliser le conteneur d'une certaine manière, comme en ajoutant sa taille à une variable globale. P>
Il semble toujours probable que le compilateur puisse optimiser la copie ici. Voir mon édition pour un échantillon de code.
Oh, OK - Appelez ensuite une fonction sur la copie et l'original.
Il est peu probable que la volatille effectue ce que vous attendez pour un type non de pod. Je recommanderais de passer un char * code> ou
vide * code> aliasant le conteneur vers une fonction vide dans une unité de traduction différente. Étant donné que le compilateur n'est pas en mesure d'analyser l'utilisation du pointeur, cela agira en tant que barrière de mémoire compilateur, forçant au moins l'objet au cache du processeur et empêchant ainsi la plupart des optimisations d'élimination de la valeur morte. P>
La norme C ++ 03 indique que lit et écrit des données volatiles est un comportement observable (C ++ 2003, 1.9 [INTRO.EXECUTION] / 6). Je crois que cela garantit que l'affectation à des données volatiles ne peut pas être optimisée. Un autre type de comportement observable est des appels aux fonctions d'E / S. La norme C ++ 11 est encore plus sans ambiguïté à cet égard: 1,9 / 8 dit explicitement que P>
Le moins d'exigences sur une implémentation conforme sont:
- L'accès à des objets volatils est évalué strictement en fonction des règles de la machine abstraite. P> blockQuote>Si un compilateur peut prouver qu'un code ne produit pas de comportement observable, il peut optimiser le code. Dans votre mise à jour (lorsque la volatilité n'est pas utilisée), le constructeur de copie et les autres appels de fonction et les opérateurs surchargés peuvent éviter tout appel d'E / S et accès à des données volatiles, et le compilateur pourrait bien comprendre. Toutefois, si
gnumcopies code> est une variable globale utilisée ultérieurement dans une expression avec un comportement observable (E. G. imprimé), ce code ne sera pas supprimé. P>
Utilise -O0 et les drapeaux -g dans le compilateur ne fonctionnent pas? Je ne pense pas que l'utilisation de volatiles est la bonne approche ici.
@RC au lieu de profilage avec
-O0 code> Vous pouvez simplement deviner l'impact de la performance à la place. Le résultat n'a de même aucune incidence sur un scénario réaliste.
@RC Je ne suis pas sûr. Je sais que les optimisations comme le RVO vont frapper même lorsque vous utilisez -O0 (voir Stackoverflow.com/questions/4767620/... ).
Si le constructeur de copie a des effets secondaires, le compilateur est-il même autorisé à optimiser la copie?
@Neil, pouvez-vous élaborer? Spécifiquement, je ne pense pas que l'une ou l'autre condition énumérée à 12,8 / 15 s'applique à cette affaire. Il n'y a pas de déclaration de retour et il n'y a pas d'objet temporaire. En outre, considérez ideone.com/ajbr1 . Même avec
g ++ -o4 code>, le constructeur de copie est appelé une fois par boucle. (Misté: oui, si le conteneur code> en question a une copie-constructeur sans effets secondaires, il peut être optimisé, pour 1,9 / 1 et 1,9 / 6. Mais je demande à propos d'un Constructeur de copie avec effets secondaires.)
@Rob, le compilateur peut optimiser tout ce qu'il peut prouver n'aura pas d'effet sur le résultat du programme. Donc, si vous créez, puis détruisez immédiatement un objet, alors en principe i>, le compilateur est absolument autorisé à optimiser le tout, à condition qu'il puisse prouver qu'il n'y a pas d'effets secondaires durables.
@bdonlan RVO est même autorisé lorsque le constructeur de copie a des effets secondaires majeurs (voir Stackoverflow.com/Questtions/4767620/... )
@bdonlan - Droite, et @stactedCooked - Droite. Mais je me demandais spécifiquement le cas où conteneur :: conteneur () a des effets secondaires. (Et RVO ne s'appliquent pas ici.)
@Rob, s'il a un effet secondaire visible, le compilateur doit conserver ces effets - mais pas sur IOTA plus. Heck, il pourrait (en principe) précalcompute tout ce que le constructeur de copie pourrait faire cela aurait des effets durables, puis simplement mettre un peu de code pour reproduire ces effets et rien d'autre.