Barrières mémoire C++ Pour Atomics
je suis un débutant quand il s'agit de ça. Quelqu'un pourrait-il fournir une explication simplifiée des différences entre les barrières de la mémoire?
- windows
MemoryBarrier();
- La clôture
_mm_mfence();
- La ligne d'assemblage
asm volatile ("" : : : "memory");
- intrinsèques
_ReadWriteBarrier();
S'il n'y a pas une explication simple quelques liens vers de bons articles ou livres serait probablement m'aider à l'obtenir directement. Jusqu'à présent, j'étais d'accord avec l'utilisation d'objets écrits par d'autres enveloppant ces appels, mais je voudrais avoir une meilleure compréhension que ma pensée actuelle qui est essentiellement le long des lignes de Il ya plus d'une façon de mettre en œuvre des barrières de mémoire sous les couvertures.
2 réponses
les deux MemoryBarrier
(MSVC) et _mm_mfence
(pris en charge par plusieurs compilateurs) fournissent une barrière de mémoire matérielle, qui empêche le processeur de se déplacer lit et écrit à travers la barrière.
la principale différence est que MemoryBarrier a des implémentations spécifiques à la plate-forme pour x86, x64 et IA64, où comme _mm_mfence utilise spécifiquement l'instruction mfence
SSE2, donc elle n'est pas toujours disponible.
sur X86 et x64 MemoryBarrier est mis en œuvre avec un xchg
et lock or
respectivement, et j'ai vu certaines affirmations que c'est plus rapide que mfence. Toutefois, mes propres repères démontrer le contraire, donc, apparemment, il est très dépendant du modèle de processeur.
une autre différence est que la mfence peut également être utilisée pour commander des stocks/charges non temporels ( movntq
etc).
GCC a également __sync_synchronize
qui génère une clôture matérielle.
asm volatile ("" : : : "memory")
dans GCC et _ReadWriteBarrier
dans MSVC fournissent seulement une barrière de mémoire de niveau de compilateur, empêchant le compilateur de réorganiser les accès de mémoire. Cela signifie que le processeur est toujours libre de réordonner.
sont généralement utilisées en combinaison avec des opérations qui ont une sorte de barrière matérielle implicite. Par exemple: sur x86 / x64 tous les magasins ont une barrière de libération et les charges ont une barrière d'acquisition, donc vous avez juste besoin d'une barrière de compilateur lors de la mise en œuvre de charge-acquérir et de stockage-libération.
voir ma réponse ici sur la sémantique matérielle des clôtures. Ce qui n'est pas mentionné, c'est qu'ils empêchent également la réorganisation des charges, des magasins ou des charges & magasins(selon la clôture) à travers clôtures, à la fois au niveau du compilateur et au niveau de la quincaillerie.