Je me suis engagé dans un désordre confus concernant la programmation multithread et j'espérais que quelqu'un puisse venir et gifler une certaine compréhension en moi.
Après avoir fait un peu de lecture, je suis entendu dire que je devrais être capable de définir la valeur d'un ensemble 64 bits atomiquement sur un système 64 bits 1 sup>. p> J'ai trouvé beaucoup de cette lecture difficile cependant, alors pensais que je voudrais essayer de faire un test pour vérifier cela. J'ai donc écrit un programme simple avec un fil qui définirait une variable dans l'une des deux valeurs suivantes: p> et un autre fil qui vérifierait la valeur de i réglez super, on dirait C'est probablement une écriture atomique ... mais j'ai alors changé le premier fil pour définir Je re-exécuté et soudainement: p> Qu'est-ce qui a changé? De toute façon, j'en attribue un grand nombre à Merci! P> p>
1: Documentation Intel CPU, Section 8.1, Opérations atomiques garanties P > foo Code>: p>
a = 1844674407370955161; code> et
b = 1144644202170355111; code>. J'exécute ce programme et n'obtiens pas de sortie m'envêtant que
bla code> n'est pas
A code> ou
B code>. P>
A code> et
b code> directement, comme: p>
foo code> - le compilateur gère-t-il un nombre constant différemment, ou j'ai tout mal compris tout? P>
3 Réponses :
La documentation d'Intel CPU a raison, alignée 8 octets lues / écrit sont toujours atomiques sur du matériel récent (même sur des systèmes d'exploitation 32 bits). P>
Ce que vous ne nous disons pas, utilisez-vous un matériel 64 bits sur un système 32 bits? Si tel est le cas, l'écriture de 8 octets sera probablement divisée dans deux 4 octets écrit par le compilateur em>. P>
Jetez un coup d'œil à la section correspondante du code d'objet. P>
Bonjour drhirsch, le système est de 64 bits Linux. Sortie Uname est: Linux ACORN 2.6.35-25-SERVER # 44 SMP VEN 11 FEV 11 15:50:10 GMT 2011 x86_64 GNU / Linux
désassemblant la boucle, je reçois le code suivant avec donc il apparaît que Références: P> gcc code>:
gcc code> utilise-t-il à 32 -bit
MOVL code> instruction avec des valeurs immédiates 32 bits. Il y a une instruction
MOVQ code> qui peut déplacer un registre 64 bits en mémoire (ou la mémoire à un registre 64 bits), mais elle ne semble pas pouvoir définir déplacer une valeur immédiate à une mémoire. Adresse, le compilateur est donc forcé d'utiliser un registre temporaire, puis de déplacer la valeur en mémoire ou d'utiliser sur
MOVL code>. Vous pouvez essayer de le forcer à utiliser un registre à l'aide d'une variable temporaire, mais cela peut ne pas fonctionner. P>
Intéressant! Merci d'avoir pris le temps de démonter ça!
Quelles options de la version compilatrice, de la plate-forme et du compilateur utilisez-vous? Cela fait une énorme différence énorme. 64 bits écrit ne sera atomique que si l'objet est aligné sur 8 octets et que le système exécute 64 bits, le mode 32 bits (OS est 32 bits (OS est 32bit ou OS est 64, mais binaire est 32) Les écritures ne seront pas atomiques
GCC 4.2, MacOS X, CPU Core I7, OS est 64 bits, le code est compilé pour l'architecture X86_64. L'écriture de valeur de 64 bits est atomique, mais les valeurs immédiates de 64 bits ne peuvent pas être représentées en opcode sous forme de @aProgrammer pointant. Donc, le compilateur doit soit copier la valeur immédiate pour vous inscrire avant de la déplacer vers la mémoire, ou il doit stocker la valeur non copieuse de la moitié de la valeur immédiate de 32 bits.
Une autre bonne réponse! Merci!
S'il y avait des instructions immédiates MOV avec une valeur de 8 octets et une adresse de 8 octets, la taille d'instructions résultante serait tout simplement terrible. Peut voir pourquoi ils ne voulaient pas construire un décodeur pour cela!
Avez-vous eu un avertissement lors de la compilation?
Je ne pense pas que ce soit le coupable, mais les littéraux ont du type INT par défaut, vous voudrez donc 1844674407370955161ull et 1144644202170355111Cull en tant que littéraux.
NIM, aucun avertissement lors de la compilation et -wall est défini
Etarion, je reçois un avertissement si ces chiffres sont à 1 chiffre de plus et doivent utiliser Ull pour vous débarrasser de l'avertissement. De toute façon, la même chose se produit.
Vous ne pouvez tout simplement pas traduire de manière fiable une garantie de la CPU en une garantie C / C ++, car vous ne savez pas ce que le compilateur fera.