J'ai lu le manuel Intel et trouvé qu'il existe un préfixe de verrouillage pour les instructions, ce qui peut empêcher les processeurs d'écrire dans le même emplacement de mémoire simultanément. Je suis assez excité à ce sujet. Je suppose que cela pourrait être utilisé comme mutex matériel. J'ai donc écrit un morceau de code pour avoir un coup. Le résultat est assez frustrant. La serrure ne prend pas en charge les instructions MOV ou LEA. Le manuel indique que Verrouiller ne prend en charge que Ajouter, ADC et, BTC, BTR, BTS, CMPXCHG, CMPXCH8B, Dec, Inc, Neg, non ou, SBB, SUB, XOR, XAD et XCHG. Quoi de plus, si le préfixe de verrouillage est utilisé avec l'une de ces instructions et que l'opérande de la source est un opérande de mémoire, une exception d'opcode non définie (#ud) peut être générée.
Je me demande pourquoi tant de limitations, de nombreuses restrictions font La serrure semble inutile. Je ne peux pas l'utiliser pour garantir une opération d'écriture générale ne pas avoir de données sales ou d'autres problèmes causés par le parallélisme. P>
E.g. J'ai écrit le code ++ (* p) dans C. P est pointeur à une mémoire partagée. L'assemblage correspondant est comme: p> J'ai ajouté "verrouillage" avant "MOVL" et "LEAL", mais le processeur se plaint "Instruction non valide". :-( Je suppose que le seul moyen de rendre les opérations d'écriture Serialized est d'utiliser le logiciel mutex, non? P> p>
5 Réponses :
Je n'appelerais certainement pas Aussi, voir Fetch-and-Ajouter . P> verrouillage code> inutile.
verrouiller cmPxchg code> est le moyen standard d'effectuer comparer-and-swap , lequel est le bloc de base de nombreux algorithmes de synchronisation. P>
Le but de verrouillage code> est de faire des opérations
Merci pour votre réponse. Je ne suis pas très sûr de ces terminologies. Je suppose que atomique signifie que l'opération sera effectuée dans un ensemble, aucune interruption, sinon annulée. Dans ce problème, même si "Serrure Ajouter" est effectué de manière atomique, si cela ne signifie pas que d'autres processeurs ne peuvent pas accéder à cet emplacement de mémoire furtivement en même temps. Donc, ce que «verrouillage» fait est d'empêcher l'accès parallèle à la même position de mémoire. Je suppose que cela s'appelle sérialiséisé, ce qui rend chaque thread accédant à la mémoire un par un.
Les opérations atomiques sont des primitives utilisées pour la sérialisation i>, mais elles ne sont pas sérialisées elles-mêmes; La sérialisation fait référence à plusieurs entités exécutant la même opération i> une à la fois, alors que les opérations atomiques préforment une opération arbitraire dans une motion discrète, non perturbée par d'autres.
Il est utile lorsque, sur une machine multiprocesseur, deux processus concurrents utilisent les mêmes données, mais ils ne peuvent pas la modifier simultanément. P>
Lorsque l'un des processus modifie les données, il utilise une serrure sur l'instruction de modification de sorte que, lorsque le second processus tente de le modifier, il faut attendre le premier à terminer son travail avant de pouvoir faire son travail avant de pouvoir faire son propre à son tour. P>
J'espère que cela aidera un peu. p>
Les processeurs X86 sont connus pour un design velu avec de nombreuses caractéristiques, de nombreuses règles et encore plus d'exceptions à toutes ces règles. Ceci est lié à la longue histoire de la famille. P>
Lorsque les compilateurs ou les personnes utilisent Le type d'instruction générale que vous semblez rechercher est appelé barrières de mémoire . En effet, X86 a plusieurs instructions "modernes" de cette famille (Mfence, Lfence, Sfence). Ils sont pleines de clôture, de clôture de chargement et de clôture de stockage respectivement. Cependant, leur importance dans le jeu d'instructions est limitée à SSE , car Intel garantit la sérialisation des écritures La partie traditionnelle de l'instruction set, et c'est à peu près la raison pour laquelle cette architecture vieillie est une cible assez facile pour la programmation multithread. P>
verrouillent code>, ils l'utilisent toujours avec toutes ses limitations, souvent sur des données spécialement introduites pour effectuer la synchronisation entre les threads, par opposition aux données d'application que les algorithmes éventuellement manipulent. On adapte ensuite les protocoles de synchronisation de fil à ce que
verrouillage code> peut faire pour eux plutôt que inversement. P>
Dans l'exemple que vous fournissez, vous pouvez utiliser un préfixe code> verrouillage code> avec un instruction Dans des cas plus généraux, vous devez utiliser des serrures. P> p> inc code> tel que ceci (en supposant
p code> est situé dans
% EAX code>):
en.wikipedia.org/wiki/fetch-and-add
EN.Wikipedia.org/wiki/compara-and-swap
Un
MOVL code> à une adresse alignée est toujours atomique, alors la serrure ne ferait aucune différence du tout.
Si ces "restrictions" n'existaient pas, les utilisations supplémentaires seraient toutes inutiles de toute façon.
BTW, il y a un problème avec votre code: même si chaque instruction a été effectuée avec une serrure de bus, le code ne serait toujours pas en sécurité, car il pouvait être interrompu entre toutes les instructions. Vous voulez que tout le bloc d'instructions soit exécuté au maximum un fil un temps. Vous avez besoin d'une approche complètement différente de celle-ci - un mutex ou similaire. Pour ce faire, vous devez fondamentalement entourer le code avec le code de verrouillage / déverrouillage - qui implique des instructions telles que "verrouiller CMPXCHG" et al
@drhirsch - Je ne pense pas que les mouvements alignés sont garantis i> atomique. Ce n'est certainement pas atomique sur les opérations 8088 (pour 16 bits) ou 386SX (pour 32 bits).
@Brianknoblauch: Ils sont garantis atomiques sur tous les transformateurs depuis 486, pour être plus précis. Je viens de supposer que nous parlions de processeurs de moins de 20 ans. Voir le Guide de programmation du système Intel Chapitre 8.1.1 "Le processeur Intel486 (et les processeurs plus récents depuis) garantit que les opérations de mémoire de base suivantes seront toujours effectuées atomiquement: • lire ou écrire un octet • lire ou écrire un mot aligné sur un 16 -Bit limite • lire ou écrire un double mot d'alignement sur une limite de 32 bits "etc.
Si vous souhaitez utiliser une instruction code> ED, une barrière de mémoire (sur un CPU qui ne prend pas en charge
mfence code> ou où
mfence code> est plus lent qu'une instruction verrouillée), vous pouvez simplement
LOCK Ajouter 0 $,% (ESP) CODE>, qui est sinon un NO-OP (à l'exception des drapeaux de clapering) et son cycle verrouillé en lecture-modification en mémoire C'est très probablement chaud dans le cache L1 et non sur un autre noyau. Autre que cela, cette question semble manquer entièrement le point du préfixe
verrouillage code>. C'est pour les écrits en lecture atomique. La barrière de mémoire complète n'est qu'un effet secondaire, mais X86 n'avait pas de barrière séparée insn jusqu'à
Mfence code>.
Dupliqué possible de est x86 CMPXCHG atomique?
@Petercordes devrait-il être dupphed martelé, semble que nous en avons aussi beaucoup ici ici Stackoverflow.com/Questtions/17020128/...
@EventRancarroll: Ce n'est pas un duplicata: il semble demander à quel point le point de verrouillage code> est s'il ne peut pas être utilisé pour créer un
MOV code> atomique. (Mais il est totalement mélangé à propos de la fabrication de l'ensemble de la RMW Atomic par rapport à la fabrication d'un
MOV code> atomique.) Il ne pose pas de questions sur CMPXCHG; Si quelque chose l'instruction souhaité est
verroue Ajouter code> ou
verrouiller xadd code>. Mais oui, j'ai démonté votre 2e lien, comme si j'essayais d'il y a des années avant d'avoir eu le représentant de le faire seul.