gcc atomique fonctions intégrées
http://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Atomic-Builtins.html
Je crois que le code suivant augmente la valeur de var atomiquement.
volatile int var = 0;
__sync_fetch_and_add( &var, 1 )
J'ai compris les codes ci-dessus comme suit logique:
- Charge l'adresse de la variable var
- écrire le numéro 1 sur la variable var, atomiquement grâce à registre/mémoire cache, en quelque sorte
Cependant, je doute que si la suite est atomique, trop
volatile int var = 0;
volatile int num = 1;
__sync_fetch_and_add( &var, num )
Car il peut être interprété comme
- Charge l'adresse de la variable var
- Charge la valeur de la variable num dans un registre
- écrire la valeur dans la variable var.
Après #2 est exécuté, mais avant #3,
le CPU/thread est interrompu et un autre CPU/thread mises à jour
la valeur de la variable num.
En d'autres termes,
lors de l'utilisation d' _sync*() de la gcc,
puis-je utiliser une variable, pas une constante, comme le deuxième argument?
N'est-ce pas briser l'atomicité?
OriginalL'auteur ddoman | 2011-07-22
Vous devez vous connecter pour publier un commentaire.
L'opération est vraiment deux opérations.
Chargement
num
est atomique. Ajouter àvar
est atomique. Mais deux opérations atomiques ne pas faire une opération atomique lorsque mis ensemble. C'est pourquoi il est si difficile d'inventer de nouvelles sans verrouillage des structures de données. En général, deux opérations thread-safe ne font pas nécessairement un "thread-safe" opération lorsque l'on compose. C'est la raison pour laquelle il est si difficile de faire corriger des applications multithread.Vous voir,
__sync_fetch_and_add
est en effet atomique, mais il se comporte comme une fonction ordinaire -- donc il prend la valeur actuelle de "num" comme paramètre. Il n'est pas tout à fait exact de dire que l'atomicité de la fonction est cassé -- parce qu'il est de la responsabilité de l'appelant pour charger la valeur denum
, et il ne fait pas partie de la fonction de l'interface. Je pourrais également se plaindre à ce sujet:Ou pire,
Vous dire qu'il "peut être interprété comme"
Mais selon le C spec, non pas qu'il peut être interprétée de cette façon, mais plutôt, il doit être interprétée de cette façon, sinon le compilateur ne serait pas conforme (en fait, il pourrait swap #1 et #2, mais ce n'est pas important ici).
Mais n'est-ce pas atomique signifie en général? En d'autres termes, une opération atomique est celui qui se produit complètement ou pas du tout, ce qui s'applique à tous les mots alignés les charges et les magasins sur de nombreuses architectures. On dirait que vous parlez des garanties de classement (fournis par les barrières de la mémoire), qui sont à un concept différent de l'atomicité -- deux opérations atomiques peut sembler se produire dans l'ordre inverse à partir d'un autre processus, mais cela ne signifie pas qu'ils ne sont pas atomiques.
Atomique dans le sens de la barrière de mémoire/cache-ligne de verrouillage/LLSC est très différente et beaucoup plus grand ensemble de concepts atomiques dans le sens de la lecture d'une plaine entier et ne pas voir le mot de les déchirer. Mais la plupart des gens ne connaissent pas la barrière de la mémoire/etc questions - je pense que la difficulté à utiliser le même mot pour les deux.
Nous n'avons pas utiliser le même mot pour les deux: les opérations atomiques sont atomiques, et les barrières de la mémoire sont les barrières de la mémoire, ce sont des concepts différents avec des noms différents. Cependant, les barrières de la mémoire peut être utilisé pour créer certaines opérations atomiques de plus primitif des opérations atomiques, et vous pouvez utiliser l'opération atomique en combinaison avec les barrières de la mémoire pour créer des primitives de synchronisation. La plupart des bibliothèques d'opérations atomiques comprennent les opérations atomiques rattachées à des obstacles car ils sont très utiles, mais ils ne sont pas la même chose.
dans GCC 4.8, __sync built-ins ont été dépréciée en faveur de l' __atomic intégrées juste laisser ça ici pour tous ceux qui souhaitent utiliser __sync
OriginalL'auteur Dietrich Epp