Quand x86 LFENCE, SFENCE et MFENCE instructions nécessaires?
Ok, j'ai lu la suite Qs de DONC en ce qui concerne CPU x86 clôtures (LFENCE
, SFENCE
et MFENCE
):
-
Il ne fait aucun sens de l'instruction LFENCE dans les processeurs x86/x86_64?
-
Quel est l'impact SFENCE et LFENCE caches des voisins des cœurs?
et:
et je dois être honnête, je ne suis pas encore complètement sûr lorsqu'une clôture est nécessaire. Je suis en train d'essayer de comprendre à partir de la perspective de la suppression entièrement soufflé serrures et d'essayer de les utiliser plus fine granular de verrouillage via les clôtures, afin de minimiser les délais de latence.
Tout d'abord voici deux questions que je ne comprends pas:
Parfois, lorsque vous faites un magasin un CPU d'écrire son tampon de stockage au lieu de la cache L1. Je n'ai cependant pas de comprendre les conditions dans lesquelles un CPU fait cela?
CPU2 peut vouloir charger une valeur qui a été écrit dans CPU1 du tampon de stockage. Si je comprends bien, le problème est CPU2 ne peut pas voir la nouvelle valeur dans CPU1 du tampon de stockage. Pourquoi ne peut pas le protocole MESI il suffit d'inclure le rinçage stocker des tampons dans le cadre de son protocole??
Plus généralement, quelqu'un pourrait veuillez tenter de décrire l'ensemble du scénario et de contribuer à expliquer quand LFENCE
/MFENCE
et SFENCE
instructions sont nécessaires?
NB l'Un des problèmes de lecture autour de ce sujet est le nombre d'articles écrits "en général" pour plusieurs architectures des processeurs, quand je suis seulement intéressé par l'Intel x86-64 de l'architecture, en particulier.
- "Pourquoi ne peut pas le protocole MESI il suffit d'inclure le rinçage stocker des tampons dans le cadre de son protocole??" Si le magasin tampons avait stricts de la commande à l'égard de l'instruction stream, ils ne servirait à rien. Sans une telle commande, quand pensez-vous éliminer? Essentiellement, votre suggestion est "pourquoi ne pas nous ralentir à la vitesse de base plutôt que d'obliger les gens à identifier les choses qui doivent subir cette peine?"
- Sur x86, vous avez à peu près de n'utiliser que de l'escrime si vous utilisez le type de mémoire autre que write-back mis en cache, ou si vous utilisez des non-temporelle des instructions. Voir aussi cette réponse, et la section du manuel qui y sont référencés.
- Sans aucune synchronisation explicite, CPU2 peut voir l'ancienne valeur, même si le magasin est déjà mis en CPU1 du tampon de stockage, il n'y a rien de mal à cela. Une seule fois CPU1 rend le magasin visible, CPU2 "doit" voir.
- Il y a un poste sur le Intel forums qui parle de l'utilisation de MFENCE: software.intel.com/en-us/forums/...
Vous devez vous connecter pour publier un commentaire.
La réponse la plus simple: vous devez utiliser l'un des 3 haies (
LFENCE
,SFENCE
,MFENCE
) de fournir l'un des 6 la Cohérence des données:C++11:
D'abord, vous devriez considérer ce problème du point de vue du degré de l'ordre d'accès à la mémoire, qui est bien documenté et normalisé en C++11. Vous devriez lire d'abord: http://en.cppreference.com/w/cpp/atomic/memory_order
x86/x86_64:
1. Acquérir Libération de la Cohérence: Ensuite, il est important de comprendre que, dans le x86 pour accéder aux classiques de RAM (marqués par défaut comme WB - Écrire de nouveau, et le même effet avec WT (Write Through) ou UC (Cache)) à l'aide de l'asm
MOV
sans commandes supplémentaires fournit automatiquement la commande de mémoire pour Acquérir Libération de la Cohérence -std::memory_order_acq_rel
.I. e. pour cette mémoire est logique de l'utiliser seulement
std::memory_order_seq_cst
seulement pour fournir Séquentielle de Cohérence. C'est à dire quand vous utilisez:std::memory_order_relaxed
oustd::memory_order_acq_rel
ensuite compilé le code assembleur pourstd::atomic::store()
(oustd::atomic::load()
) sera le même - seulementMOV
sansL/S/MFENCE
.Remarque: Mais vous devez savoir, que non seulement le CPU mais et C++compilateur peut réordonner les opérations avec la mémoire, et tous les 6 barrières de mémoire affectent toujours sur le C++compilateur indépendamment de l'architecture du PROCESSEUR.
Ensuite, vous devez savoir, comment peut-il être compilé en C++ à l'ASM (code machine natif) ou comment pouvez-vous écrire sur l'assembleur. Afin de fournir une Cohérence exclure Séquentiel, vous pouvez simplement écrire
MOV
, par exempleMOV reg, [addr]
etMOV [addr], reg
etc.2. Séquentiel de la Cohérence:, Mais de fournir des Séquentielle Consistance que vous devez utiliser implicite (
LOCK
) ou explicite des clôtures (L/S/MFENCE
) comme décrit ici: Pourquoi GCC n'a pas de CHARGE d'utilisation(sans barrière) et de les STOCKER+SFENCE pour Séquentielle de Cohérence?LOAD
(sans barrière) etSTORE
+MFENCE
LOAD
(sans barrière) etLOCK XCHG
MFENCE
+LOAD
etSTORE
(sans barrière)LOCK XADD
( 0 ) etSTORE
(sans barrière)Par exemple, GCC utilise 1, mais MSVC utilise 2. (Mais vous devez le savoir, que MSVS2012 a un bug: La sémantique de `std::memory_order_acquire " exige que les instructions du processeur x86/x86_64? )
Ensuite, vous pouvez lire Herb Sutter, votre lien: https://onedrive.live.com/view.aspx?resid=4E86B0CF20EF15AD!24884&app=WordPdf&authkey=!AMtj_EflYn2507c
Exception à la règle:
Cette règle est vraie pour l'accès à l'aide
MOV
classiques RAM marqués par défaut comme WB - Écrire de nouveau. La mémoire est de marquage dans la La Table Des Pages, dans chaque PTE (Page Table Enrty) pour chaque Page (4 KO de mémoire continu).Mais il existe quelques exceptions:
Si nous les marques de la mémoire dans la Table des pages à Écrire Combiné (
ioremap_wc()
dans POSIX), alors automatiquement fournit seulement Acquérir une Consistance, et nous devons agir comme dans le paragraphe suivant.Voir la réponse à ma question: https://stackoverflow.com/a/27302931/1558037
Dans les deux cas 1 & 2, vous devez utiliser d'autres
SFENCE
entre les deux écrit à la même adresse même si vous souhaitez Acquérir Libération de la Cohérence, car ici automatiquement fournit seulement Acquérir une Consistance et vous devez faire de la Libération (SFENCE
) de vous-même.Réponse à vos deux questions:
Du point de vue de l'utilisateur, le cache L1 et Tampon de stockage agir différemment. L1 rapide, mais en Magasin Tampon plus rapidement.
Magasin de la mémoire Tampon est une simple File d'attente, où les magasins seulement Écrit, et qui ne peuvent être réorganisées - il est fait pour augmenter la performance et de Masquer la Latence d'accès à la mémoire cache (L1 - 1ns, L2 - 3n, L3 - 10ns) (PROCESSEUR-Core pense que l'Écriture est stocké dans le cache et exécute la commande suivante, mais en même temps, de vos Écritures enregistrées uniquement à la mémoire-Tampon et sera enregistré dans le cache L1/2/3 plus tard), c'est à dire du PROCESSEUR-Core n'avez pas besoin d'attendre lors de l'Écrit aura été stockée en mémoire cache.
Cache L1/2/3 - ressembler transparent associé array (adresse, valeur). Il est rapide mais pas le plus rapide, parce que x86 fournit automatiquement à Acquérir-Communiqué de Cohérence à l'aide de cache cohérent protocole MESIF/MOESI. Il est fait pour simplifier la programmation multithread, mais une baisse de la performance. (Vraiment, nous pouvons Écrire les Querelles de Libre-algorithmes et structures de données sans utiliser de cache cohérente, c'est à dire sans MESIF/MOESI par exemple sur PCI Express). Les protocoles MESIF/MOESI fonctionne sur QPI qui relie les Cœurs de CPU et de Cœurs de processeur entre les différents Processeurs dans les systèmes multiprocesseurs (ccNUMA).
Oui.
MESI protocole ne pouvez pas inclure de rinçage stocker des tampons dans le cadre de son protocole, parce que:
Mais la main de rinçage Tampon de stockage actuelle de l'UC-Core - oui, vous pouvez le faire exécuter par
SFENCE
de commande. Vous pouvez utiliserSFENCE
dans deux cas:Remarque:
Faire nous avons besoin de
LFENCE
en tout cas sur x86/x86_64? - la question n'est pas toujours claire: Il ne fait aucun sens de l'instruction LFENCE dans les processeurs x86/x86_64?Autre plate-forme:
Ensuite, vous pouvez lire comme dans la théorie (pour une sphère de processeur dans le vide) avec Store-Tampon et d'Invalider la le d'Attente, votre lien: http://www.puppetmastertrading.com/images/hwViewForSwHackers.pdf
Et comment assurer la Cohérence Séquentielle sur d'autres plates-formes, non seulement avec L/S/MFENCE et SERRURE, mais et avec LL/SC: http://www.cl.cam.ac.uk/~pes20/cpp/cpp0xmappings.html
LFENCE
etSFENCE
séparément demfence
. Vous avez seulement besoin SFENCE lors de l'utilisation de NT magasins. Vous avez à peu près jamais besoin LFENCE à tous pour mémoire réelle de la commande, pour sa seule partie de la sérialisation d'effet, par exemple avecrdtsc
(Pourquoi est (ou n'est-ce pas?) SFENCE + LFENCE équivalent à MFENCE? et Quand dois-je utiliser _mm_sfence _mm_lfence et _mm_mfence).mfence
est la seule barrière qui est utile pour la mémoire de la commande.lfence
etsfence
ne sont pas utiles pour l'un de détendu à seq_cst