La structure de données standard union/find or Disjoint-set a de très bons temps de fonctionnement (effectivement O(1)
) pour les boîtiers à un seul filetage. Cependant, quelle est sa validité/performance sous des cas multi-threadés? Je pense qu'il est totalement valide même sans verrouillage ou toutes les opérations atomiques en dehors des écritures de taille atomique pointeur.Le thread de l'algorithme union/find normal est-il sûr sans travail supplémentaire?
Est-ce que quelqu'un voit des problèmes avec la logique suivante?
D'abord, je suppose que les écritures de taille de pointeur sont atomiques. De cela, il n'est pas difficile d'argumenter que vous pouvez exécuter la fonction
find
en toute sécurité dans plusieurs threads car les seules mises à jour qui se produiront sont tous les jeux à la même valeur. Si vous autorisez la fonctionfind
à renvoyer la réponse qui était vraie quand elle a été appelée (par opposition à quand elle est retournée), il n'est pas difficile d'argumenter que beaucoup defind
et un seulunion
peuvent être exécutés en même temps; l'argument pour lefind
ne change pas et leunion
ne met à jour que les racines et lesfind
ne mettent jamais à jour les racines. Comme pour le cas restant (plusieursunion
s), je pense que cela fonctionne aussi bien mais je ne suis pas si sûr de lui.
BTW: Je ne demande pas que la solution soit aussi efficace que la version à un seul filetage. (Afin d'éviter les serrures/atomiques, je suis également prêt à rejeter globalement état cohérent.)
modifier: prendre un autre regard, les cas de nombreux syndiqués ne fonctionne pas parce que si le côté qui n'est pas la nouvelle racine est unie avec autre chose (pas aussi comme une racine), alors vous pourriez le couper de l'autre côté de la deuxième union.
A = find(a) // union 1
B = find(b) // union 1
----
X = find(x) // union 2 (x == a) -> (X == A) -> (X.par aliases A.par)
Y = find(y) // union 2
X.par = Y // union 2
----
A.par = B // union 1
cela peut être évité avec un CAS:
while(!CAS(A == A.par, B)) A = find(A);
Je pense que même avec le TAS, deux tentatives parallèles à l'union A et B pourrait créer un cycle entre A et B. – Dave