0
votes

Avons-nous besoin d'utiliser la serrure pour un système X32 multi-filetés pour simplement lire ou écrire dans une variable UINT32_T

J'ai une question: Considérons un système X32, Par conséquent, pour une variable UINT32_T, le système lut-il et écrit-il atomiquement? Signification, que toute l'opération de lecture ou d'écriture peut être complétée dans un cycle d'instruction. Si tel est le cas, alors pour un système X32 multi-threadé, nous n'avons pas à utiliser des serrures pour simplement lire ou écrire dans une variable UINT32_T. S'il vous plaît confirmer ma compréhension.


1 commentaires

Le gros problème est un cycle de lecture-écriture en lecture-modification des variables. Comme par exemple x ++ ou x + = y .


4 Réponses :


2
votes

L'utilisation des serrures n'est pas (uniquement) pour assurer l'atomicité, des variables 32 bits ont déjà été écrites atomiquement.

Votre problème est de protéger l'écriture simultanée: xxx < p> S'il n'y a pas de synchronisation, x pourrait mettre fin à 1 au lieu de 2 car la fonction 2 peut être la lecture x = 0 , avant la fonction 1 modifie x. La pire chose dans tout cela est que cela pourrait arriver ou non au hasard (ou au PC de votre client), le débogage est donc difficile.


8 commentaires

variables 32 bits sont déjà écrits atomiquement - ils ne sont pas


@Vtt comment alors? au niveau de l'assemblée, ils sont.


@Michaelchourdakis ne présume jamais quoi que ce soit sur l'assemblée.


@Anttihaapala Lorsque si votre compilateur est gravement bizarre, quand il le fait x = 5, il l'écrit atomiquement, pas un peu à peu.


@MichaelchourDakis comme je l'ai dit ne rien assumer quoi que ce soit. La norme C dit que ce n'est pas bien, donc à un moment donné, ce n'est pas bien.


En outre, il n'y a pas beaucoup de programmes utiles en outre / bin / true ou / bin / faux qui pourrait simplement utiliser des constantes partout;)


Sur les opérations atomiques x86, y compris un magasin atomique simple, a des exigences d'alignement strictes. Donc, par exemple, une seule instruction MOV n'est pas garantie d'être atomique. Si la valeur traverse la limite de la ligne de cache, il est garanti d'être pas atomique.


@Vttt mais donc c sur x86



3
votes

Oui, il faut utiliser des serrures ou un autre mécanisme approprié, comme l'atomique.

C11 5.1.2.4p4 : < / p>

  1. Deux évaluations d'expression conflit Si l'un d'entre eux modifie un emplacement de mémoire et l'autre lit ou modifie le même emplacement de la mémoire.

    C11 5.1.2.4P25 : < / p>

    1. L'exécution d'un programme contient une course de données s'il contient deux actions conflictuelles dans différents threads, au moins l'une d'entre elles n'est pas atomique et ne se produit pas non plus avant l'autre. Une telle course de données entraîne un comportement non défini.

      En outre, si vous avez une variable qui n'est pas volatile qualifiée, la norme C n'exige même pas que les modifications touchent le tout à la mémoire; À moins que vous n'utilisiez un mécanisme de synchronisation, les races de données pourraient avoir beaucoup plus debout dans un programme optimisé que d'être autrement pensé pourraient peut-être être possibles - par exemple, les écritures peuvent être totalement hors de l'ordre, etc.


0 commentaires

3
votes

Il est seulement atomique si vous écrivez le code dans l'assembleur et choisissez l'instruction appropriée. Lorsque vous utilisez un langage de niveau supérieur, vous n'avez aucun contrôle sur les instructions qui seront cueillies.

Si vous avez du code C comme a = b; , le code de la machine généré peut être "charger B dans le registre X" ", enregistre le registre X dans l'emplacement de la mémoire d'A", qui est plus d'une instruction. Une interruption ou un autre fil exécuté entre ces deux signifiera la corruption des données s'il utilise la même variable. Supposons que l'autre thread écrit une valeur différente à A - alors ce changement sera perdu lors du retour au fil d'origine.

Par conséquent, vous devez utiliser une manière de mécanisme de protection, telle que _atomic qualificatif, mutex ou des sections critiques.


0 commentaires

0
votes

Le problème est que les variables ne sont pas mises à jour instantanément.

Le noyau de chaque processeur a sa propre mémoire privée (Caches L1 et L2). Donc, si vous modifiez une variable, disons x ++ , dans deux threads différents sur deux noyaux différents -, chaque noyau met à jour sa propre version de x .

Les opérations atomiques et les mutiles assurent la synchronisation de ces variables avec la mémoire partagée (cache RAM / L3).


0 commentaires