Sont des barrières de mémoire nécessaire pour le comptage de référence atomique partage des données immuables?

StackOverflow https://stackoverflow.com/questions/2599238

Question

J'ai quelques structures de données immuables que je voudrais gérer à l'aide des décomptes de références, de les partager entre les threads sur un système SMP.

Voici ce que le code de libération ressemble à:

void avocado_release(struct avocado *p)
{
    if (atomic_dec(p->refcount) == 0) {
        free(p->pit);
        free(p->juicy_innards);
        free(p);
    }
}

Est-ce que atomic_dec besoin d'une barrière de mémoire en elle? Si oui, quel genre de barrière de mémoire?

Notes complémentaires: L'application doit fonctionner sur PowerPC et x86, de sorte que toute l'information spécifique au processeur est accueilli. Je sais déjà sur les builtins atomiques du CCG. En ce qui concerne immuabilité, le refcount est le seul champ qui change pendant toute la durée de l'objet.

Était-ce utile?

La solution

Sur x86, il se transforme en une instruction de montage préfixé de verrouillage, comme LOCK XADD.
Être une instruction unique, il est non interruptible. En tant ajouté « feauture », les résultats de préfixe de verrouillage dans une barrière de mémoire pleine:

  

« ... les opérations verrouillées sérialisent toutes les opérations de chargement et de stockage en circulation (qui est, d'attendre qu'ils viennent compléter). » ... "opérations Locked sont atomiques par rapport à toutes les autres opérations de mémoire et tous les événements visibles de l'extérieur. Instruction seulement fetch et accès de table de page peut transmettre des instructions verrouillées. Instructions verrouillées peuvent être utilisées pour synchroniser les données écrites par un processeur et lu par un autre processeur « . - Intel® 64 et IA-32 Architectures Logicielles Manuel de développeur, chapitre 8.1.2.

Une barrière de mémoire est en fait mis en oeuvre en tant que LOCK OR factice ou LOCK AND à la fois .NET et JAVA JIT sur x86 / x64.
Donc, vous avez une clôture complète sur x86 comme un bonus supplémentaire, que vous le vouliez ou non. :)

Sur PPC, il est différent. LL / SC paire - lwarx & stwcx - avec une soustraction à l'intérieur peut être utilisé pour charger l'opérande de mémoire dans un registre, soustraire une, alors soit l'écrire en arrière s'il n'y avait pas d'autre magasin à l'emplacement cible, ou recommencer la boucle entière s'il y avait. Un LL / SC peut être interrompue.
Elle ne signifie pas une clôture automatique complète.
Cela ne signifie toutefois pas compromettre l'atomicité du compteur de quelque façon.
Cela signifie simplement que dans le cas x86, il vous arrive d'obtenir une clôture ainsi « gratuitement »,.
Sur PPC, on peut insérer une clôture complète en émettant un (lw)sync instruction .

Dans l'ensemble, les barrières de mémoire explicites ne sont pas nécessaires pour le compteur atomique fonctionne correctement.

Autres conseils

Il est important de faire la distinction entre des accès atomiques (qui garantissent que la lecture / modification / écriture de la valeur exécute comme une unité atomique) et remise en ordre de la mémoire.

barrières de mémoire empêchent réordonnancement de lit et écrit et réordonnancement est complètement orthogonal à atomicité. Par exemple, sur PowerPC si vous implémentez alors l'incrément atomique la plus efficace possible, il n'empêchera pas réordonner. Si vous voulez éviter réorganisant alors vous avez besoin d'une barrière de mémoire lwsync ou une instruction de synchronisation, ou d'un haut niveau équivalent (11 C ++?).

Les allégations selon lesquelles il n'y a « aucune possibilité de choses réordonnancement compilateur de manière problématique » semble naïve que les déclarations générales, car les optimisations du compilateur peuvent être tout à fait surprenant et parce que les processeurs (PowerPC / ARM / Alpha / MIPS en particulier) réordonner agressivement les opérations de mémoire .

Un cache cohérent ne vous sauve pas non plus. Voir http://preshing.com/ pour voir comment fonctionne vraiment réordonnancement mémoire.

Dans ce cas, cependant, je crois que la réponse est qu'aucun obstacle sont nécessaires. C'est parce que pour ce cas précis (comptage de référence) il n'y a pas besoin d'une relation entre le nombre de référence et les autres valeurs de l'objet. La seule exception est lorsque le nombre de référence atteint zéro. A ce stade, il est important de veiller à ce que toutes les mises à jour d'autres sujets sont visibles pour le thread courant si une barrière lecture-acquire peut nécessaire.

Êtes-vous l'intention de mettre en œuvre votre propre atomic_dec ou vous demande si une fonction fournie par le système se comporte comme vous voulez?

En règle générale, les installations incrémenter / décrémenter atomiques fournis par le système appliquera tout les obstacles mémoire sont nécessaires pour le faire la bonne chose. Vous ne devez généralement pas à se soucier des barrières de mémoire à moins que vous faites quelque chose de farfelu comme la mise en œuvre de vos propres structures de données sans blocage ou une bibliothèque STM.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top