Ce n'chaque memory_order veux dire?
J'ai lu un chapitre et je ne l'aime pas beaucoup. Je ne suis toujours pas clair quelles sont les différences entre chaque mémoire de l'ordre. C'est mon actuel de la spéculation qui j'ai compris après la lecture de beaucoup plus simple http://en.cppreference.com/w/cpp/atomic/memory_order
Le ci-dessous est faux, alors n'essayez pas d'apprendre
- memory_order_relaxed: Ne se synchronise pas, mais n'est pas ignorée lors de la commande est effectué à partir d'un autre mode dans un autre atomique var
- memory_order_consume: Synchronise la lecture de cette variable atomique cependant Il ne marche pas de synchronisation détendu vars écrit avant cette. Toutefois, si le thread utilise var X lors de la modification de Y (et la lance). Les autres threads consommant Y voir X publié aussi bien? Je ne sais pas si cela signifie que ce thread pousse les changements de x (et évidemment y)
- memory_order_acquire: Synchronise la lecture de cette variable atomique ET permet de s'assurer détendu vars écrit avant ce sont synchronisés ainsi. (est-ce à dire tous atomique variables sur tous les threads sont synchronisés?)
- memory_order_release: Pousse la atomique en magasin pour les autres threads (mais seulement si ils ont lu le var à consommer/acquisition)
- memory_order_acq_rel: lecture/écriture de la fpo. Un acquérir de sorte que vous n'avez pas à modifier une ancienne valeur et libère les modifications.
- memory_order_seq_cst: La même chose que d'acquérir communiqué que les mises à jour pour être vu dans d'autres threads (si
a
magasin avec détendue sur un autre thread. J'magasinb
avec seq_cst. Un 3ème fil de la lecturea
avec détendez-vous verrez des changements avecb
et toute autre variable atomique?).
Je crois que j'ai compris, mais corrigez-moi si je me trompe. Je ne pouvais pas trouver quelque chose qui l'explique dans un format facile à lire l'anglais.
- J'ai lu le premier, qui n'a pas beaucoup d'aide. Le 2ème n'est même pas lié.
- Je doute que cela ne sera jamais "facile à lire". La mémoire de la commande est juste en soi un très compliquée et très subtile sujet. Je ne vais pas tenter de l'expliquer mieux que ce document.
- le problème de ce document (ou de hpl.hp.com/techreports/Compaq-DEC/WRL-95-7.pdf qui est une autre bonne introduction aux questions), c'est que leur terminologie n'est pas en ligne avec celle utilisée dans la norme.
- Je pense acquérir afin impose une lecture de la barrière avant de la charge, et l'ordre de sortie impose une barrière d'écriture après le magasin... d'Acquérir de commande empêche la descente de la charge, et la libération empêche la remontée de la boutique.
- correct, je ne pense pas que cette phrase est difficile à comprendre. Maintenant, si vous pouvez expliquer comment memory_order_seq_cst est différente de memory_order_acq_rel je serais heureux 😉
- acqrel signifie "acquérir pour les charges, libération pour les magasins" (par exemple, pour comparer-échange, où vous obtenez soit une charge ou d'un magasin, selon que la valeur attendue est toujours d'actualité). Séquentielle cohérence implique une inconditionnelle de plein barrière.
- Il y a un total de la commande. Voir stackoverflow.com/questions/12340773/... pour les cas où des questions.
- Je pense que le C++ modèle est plus faible que celle (c'est à dire que vous pouvez y arriver de cette façon mais il y a des choses qui sont autorisés en C++ qui ne peut pas se produire avec l'utilisation du noyau Linux, obstacles). Mais pour confirmer que j'aurais du relire attentivement les définitions du noyau Linux, les obstacles.
- Le GCC Wiki explique beaucoup mieux, à mon avis.
- C'est la meilleure explication que j'ai jamais vu. Je souhaite que j'ai vu avant
- Envisagez-vous de faire votre commentaire une réponse? La raison en est que votre commentaire fournit de l'information utile à quelqu'un (comme moi) qui trouve plus tard la question de Stackoverflow des archives. (Aussi, si vous répondez ici, alors que je suis informé, je vais upvote la réponse.)
- Ajout d'un extrait, voir ci-dessous.
Vous devez vous connecter pour publier un commentaire.
La GCC Wiki donne un très complet et facile à comprendre des explications avec des exemples de code.
(extrait modifié, et l'emphase ajoutée)
IMPORTANT:
Lors de la re-lecture de la citation ci-dessous copié à partir de la GCC Wiki dans le processus d'ajout de ma propre formulation de la réponse, j'ai remarqué que la citation est en fait mal. Ils ont obtenu acquérir et consommer exactement à l'envers. Un de presse-consommer opération ne fournit qu'une commande de garantie sur les données dépendantes tandis qu'un de presse-acquérir opération prévoit que la garantie indépendamment des données dépend de la valeur atomique ou pas.
Voici ma propre tentative d'explication plus terre à terre:
Une approche différente de voir les choses est de regarder le problème du point de vue de la réorganisation des lectures et écritures, les deux atomique et ordinaire:
Tous opérations atomiques sont garantis pour être atomiques à l'intérieur d'eux-mêmes (la combinaison de deux opérations atomiques n'est pas atomique dans son ensemble!) et pour être visible dans le total de l'ordre dans lequel ils apparaissent sur la ligne de montage du flux d'exécution. Cela signifie qu'aucune opération atomique peut, en aucun cas, être réorganisées, mais d'autres opérations de mémoire pourrait très bien l'être. Les compilateurs (et Cpu) systématiquement faire une telle réorganisation comme une optimisation.
Il signifie également que le compilateur doit utiliser quelles que soient les instructions sont nécessaires pour garantir qu'une opération atomique de l'exécution à tout moment voir les résultats de chaque et tous les autres opération atomique, éventuellement sur un autre processeur core (mais pas nécessairement d'autres opérations), qui ont été exécutés avant.
Maintenant, un détendu est juste que le strict minimum. Il ne fait rien de plus et ne fournit aucune autre garantie. C'est la moins chère possible opération. Pour les non-lecture-modification-écriture des opérations sur fortement commandé les architectures de processeur (par exemple x86/amd64) cela se résume à un simple normal, ordinaire déplacer.
La séquentiellement cohérente fonctionnement est exactement le contraire, elle met en application stricte de la commande, non seulement pour les opérations atomiques, mais aussi pour d'autres opérations de mémoire qui se produisent avant ou après. Aucun d'eux ne peut traverser la barrière imposée par l'opération atomique. Pratiquement, cela signifie perte de possibilités d'optimisation, et éventuellement de clôture des instructions peut être inséré. C'est le modèle le plus cher.
Un libération opération empêche ordinaire des charges et des magasins de la réorganisation après l'opération atomique, alors qu'un acquérir opération empêche ordinaire des charges et des magasins de la réorganisation avant l'opération atomique. Tout le reste peut encore être déplacé autour de.
La combinaison de la prévention des magasins étant déplacé après, et des charges de déplacés avant l'opération atomique permet de s'assurer que, quelle que soit l'acquisition de fil est à voir, c'est compatible, avec seulement une petite quantité de l'optimisation de l'occasion perdue.
On peut penser que quelque chose comme un non-existant de verrouillage qui est libérée (par l'auteur) et acquis (par le lecteur). Sauf que... il n'y a pas de serrure.
Dans la pratique, la libération/acquérir généralement signifie que le compilateur a besoin de ne pas utiliser tout particulièrement coûteux instructions spéciales, mais il ne peut pas réorganiser librement des charges et des magasins à son goût, qui peuvent manquer certains (petits) optimisation opportuntities.
Enfin, consommer est la même opération que acquérir, seulement avec l'exception que la commande des garanties s'appliquent uniquement aux données dépendantes. Les données dépendantes serait, par exemple, être des données est indiqué par un atomiquement modifiés pointeur.
Sans doute, que peut fournir pour un couple de possibilités d'optimisation qui ne sont pas présents à acquérir des opérations (depuis moins de données est soumis à des restrictions), cependant, cela se fait au détriment des plus complexes et plus le risque d'erreur de code, et la tâche non triviale de l'obtention de la dépendance des chaînes correctes.
Il est actuellement déconseillé d'utiliser consommer de commande alors que le cahier des charges est en cours de révision.
dependent variables
dans le cas dememory_order_acquire/memory_order_release
?relaxed
est un peu plus que juste une plaine normale de lecture/écriture; elle garantit que de lecture/écriture ne sont pas des "déchiré" qui permet de mettre en œuvre la déchirure gratuit de variables partagées, sans imposition de barrières de mémoire. Voir Preshing de travail sur ce sujet ici: preshing.com/20130618/atomic-vs-non-atomic-operations ...ainsi qu'un exemple de la relâche des "drapeaux" ici, avec acquisition/diffusion des clôtures pour s'assurer de séparer les structures de données sont correctement engagés à et lecture de la mémoire: preshing.com/20130922/acquire-and-release-fencesCeci est un sujet complexe. Essayez de lire http://en.cppreference.com/w/cpp/atomic/memory_order plusieurs fois, essayer de lire d'autres ressources, etc.
Voici une description simplifiée:
Le compilateur et CPU pouvez réorganiser les accès à la mémoire. C'est qu'ils peuvent arriver dans un ordre différent que ce qui est spécifié dans le code. C'est très bien la plupart du temps, le problème se pose lorsque le thread différent essayer de communiquer et peut voir l'ordre d'accès à la mémoire qui brise les invariants du code.
Habituellement, vous pouvez utiliser des verrous pour la synchronisation. Le problème est qu'ils sont lents. Les opérations atomiques sont beaucoup plus rapide, parce que la synchronisation se produit au niveau CPU (c'est à dire de l'UC s'assure qu'aucun autre thread, même sur un autre PROCESSEUR, modifie certaines variables, etc.).
Donc, le seul problème auquel nous sommes confrontés est la réorganisation de l'accès à la mémoire. Le
memory_order
enum précise quels types de reorderings compilateur doit interdire.relaxed
- pas de contraintes.consume
- pas de charges qui dépendent de la nouvellement chargée de la valeur peuvent être réorganisés wrt. la atomique en charge. I. e. si ils sont après la atomique en charge dans le code source, ils arriver après la atomique en charge trop.acquire
- pas de charges peuvent être réorganisés wrt. la atomique en charge. I. e. si ils sont après la atomique en charge dans le code source, ils arriver après la atomique en charge trop.release
- pas de magasins peuvent être réorganisés wrt. l'atomic store. I. e. si ils sont devant le atomique en magasin dans le code source, ils arriver avant l'atomic store.acq_rel
-acquire
etrelease
combiné.seq_cst
- il est plus difficile de comprendre pourquoi cette commande est requise. Fondamentalement, tous les autres ordres seulement de s'assurer que spécifique refusé reorderings ne se produit pas uniquement pour les threads qui consomment de l'/libération de la même variable atomique. Les accès à la mémoire peut encore se propager à d'autres threads dans n'importe quel ordre. Cette commande assure que cela ne se produise pas (donc séquentielle de la cohérence). Pour un cas où cela est nécessaire, voir l'exemple à la fin de la page liée.