8
votes

Utilise "Pointeur à volatil" Empêcher les optimisations du compilateur à tout moment?

Voici le problème: Votre programme temporairement Utilise des données sensibles et veut l'effacer quand il n'est plus nécessaire . Utilisation de std :: Remplissage () On lui aide toujours toujours - le compilateur peut décider que le bloc de mémoire n'est pas accessible ultérieurement, alors l'effacement est une perte de temps et éliminer l'effacement du code.

Utilisateur ybungalobill suggère Utilisation volatile mot-clé : xxx

L'intention est que lors de la vue du mot clé volatile Le compilateur n'essaiera pas d'éliminer l'appel à std :: Fill_N () .

sera < Code> Volatile Le mot-clé empêche toujours le compilateur de cette mémoire modifiant la mémoire d'élimination du code?


3 commentaires

Hmmm, je pense que ce n'est pas la situation exacte. Ici, le compilateur sait que la mémoire est allouée sur la pile, il n'y a pas. (Donc, cela peut indiquer un registre mappé de mémoire)


J'étais sur le point de poster une question similaire concernant cette réponse. Funny Comment une préoccupation peut collecter beaucoup d'autres questions intéressantes;) Voici mon +1.


Essayez de déclarer la mémoire tampon sous forme de mémoire tampon [Taille] volatile [Taille]; plutôt que de la jeter dans l'appel à std :: Fill_n .


4 Réponses :


3
votes

du dernier brouillon C ++ 0x [INTRO.EXECUTION]:

8 le moins d'exigences sur un La mise en œuvre conforme est:

- L'accès à des objets volatils sont évalué strictement selon le Règles de la machine abstraite.

[...]

12 Accéder à un objet désigné par un Glvalue volatile (3.10), modifiant un objet, appelant une bibliothèque E / S fonction ou appeler une fonction qui Est-ce que l'une de ces opérations sont toutes effets secondaires, [...]

Donc, même le code que vous avez fourni ne doit pas être optimisé.


1 commentaires

Au moins, les effets secondaires de l'écriture à des objets volatils ne doivent pas être supprimés sous la règle AS-si, ce qui signifie que le code fait ce qu'il devrait. Le compilateur est toujours libre d'effectuer d'autres optimisations dans Fill_N , telles que la boucle déroulante ou les optimisations de peephole d'assembleur.



1
votes

Le contenu de la mémoire que vous souhaitez supprimer peut avoir déjà été rincé de votre cache interne de la CPU / CORE en RAM, où d'autres processeurs peuvent continuer à le voir. Après avoir écrasé, vous devez utiliser une instruction de mouton / barrière de mémoire / une opération atomique ou quelque chose pour déclencher une synchronisation avec d'autres cœurs. Dans la pratique, votre compilateur fera probablement cela avant d'appeler des fonctions externes (Google Dave Butenhof's Post sur l'utilitaire douteux de volatile dans la multi-threading), de sorte que si vous le filetez-le, il n'est donc pas un problème majeur. Sommairement: la volatilité n'est pas nécessaire.


0 commentaires

3
votes

Le compilateur est libre d'optimiser votre code car tampon n'est pas un objet volatil .

La norme nécessite uniquement qu'un compilateur adhère strictement à la sémantique des objets volatils. Voici ce que C ++ 03 dit

Le moins d'exigences sur une implémentation conforme sont:

  • sur des points de séquence, des objets volatils sont stables dans le sens où les évaluations précédentes sont complètes et Les évaluations ultérieures n'ont pas encore eu lieu. [...]

    et

    Le comportement observable de la machine abstraite est sa séquence de lecture et écrit aux données volatiles et Appels vers les fonctions d'E / S de la bibliothèque

    Dans votre exemple, ce que vous avez est lu et écrit à l'aide d'objets volatils à des objets non volatils. C ++ 0x a supprimé le deuxième texte que j'ai cité ci-dessus, car il est redondant. C ++ 0x dit simplement

    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. [...]

      Celles-ci collectivement sont appelées comportement observables du programme.

      On peut affirmer que "les données volatiles" pourrait peut-être signifier "les données accessibles par des lvalues ​​volatiles", qui seraient toujours assez étirées, le libellé C ++ 0x a supprimé tous les doutes sur votre code et permet clairement des implémentations de l'optimiser loin.

      Mais comme les gens m'ont souligné, cela n'a probablement pas d'importance dans la pratique. Un compilateur qui optimise une telle chose va probablement aller contre l'intention des programmeurs (pourquoi quelqu'un aurait-il un pointeur à volatilité autrement) et contiendrait probablement un bug. Néanmoins, j'ai connu des vendeurs compilateurs qui ont cité ces paragraphes lorsqu'ils étaient confrontés à des bugReports sur leurs optimisations trop agressives. En fin de compte, volatile est spécifique à la plate-forme inhérente et vous êtes censé vérifier le résultat de toute façon.


1 commentaires

_Pourquoi ces règles ont tendance à jouer avec des mots?



1
votes

Une implémentation conforme peut, à sa loisirs, différer les performances réelles de toutes les lectures volatiles et écrites jusqu'à ce que le résultat d'une lecture volatile affecterait l'exécution d'une opération d'écriture volatile ou d'E / S.

Par exemple, donné quelque chose comme: xxx

un compilateur conforme pourrait, à son option, vérifier si échelle est un multiple de 128 et - si oui - clair Toutes les valeurs même indexées de res avant de faire des lectures de vol1 ou écrit sur vol2 . Même si le compilateur aurait besoin de faire chaque lecture de vol1 avant de pouvoir effectuer l'écriture suivante sur vol2 , un compilateur peut être capable de différer les deux opérations jusqu'à ce qu'il soit exécuté une quantité de code essentiellement illimitée.


0 commentaires