web-dev-qa-db-fra.com

La synchronisation avec `std :: mutex` est-elle plus lente qu'avec` std :: atomic (memory_order_seq_cst) `?

La raison principale de l'utilisation d'atomes sur les mutex est que les mutex sont chers, mais avec le modèle de mémoire par défaut pour atomics étant memory_order_seq_cst, N'est-ce pas aussi cher?

Question: Un programme simultané utilisant des verrous peut-il être aussi rapide qu'un programme simultané sans verrou?

Si c'est le cas, cela ne vaut peut-être pas la peine à moins que je veuille utiliser memory_order_acq_rel Pour atomique.


Edit: il me manque peut-être quelque chose, mais le verrouillage ne peut pas être plus rapide que le verrouillage sans verrouillage car chaque verrou devra également être une barrière de mémoire complète. Mais avec lock-free, il est possible d'utiliser des techniques moins restrictives que les barrières mémoire.

Donc, revenons à ma question, est-ce que le verrouillage est plus rapide que le verrouillage basé sur la nouvelle norme C++ 11 avec par défaut memory_model?

Est-ce que "lock-free> = basé sur le verrouillage lorsque mesuré en performance" est vrai? Supposons 2 threads matériels.


Edit 2: Ma question ne concerne pas les garanties de progression, et peut-être que j'utilise "sans verrouillage" hors contexte.

Fondamentalement, lorsque vous avez 2 threads avec mémoire partagée et que la seule garantie dont vous avez besoin est que si un thread écrit, l'autre thread ne peut ni lire ni écrire, je suppose qu'une simple opération atomique compare_and_swap Serait beaucoup plus rapide que de verrouiller un mutex.

Parce que si un thread ne touche même jamais la mémoire partagée, vous finirez par verrouiller et déverrouiller encore et encore sans raison, mais avec des opérations atomiques, vous n'utilisez qu'un seul cycle de processeur à chaque fois.

En ce qui concerne les commentaires, un verrou tournant par rapport à un verrou mutex est très différent lorsqu'il y a très peu de conflit.

33
jaybny

La programmation sans verrouillage concerne garanties de progression: Du plus fort au plus faible, ceux-ci sont sans attente , sans verrouillage , sans obstruction , et bloquant .

Une garantie coûte cher et a un prix. Plus vous voulez de garanties, plus vous payez. Généralement, un algorithme de blocage ou une structure de données (avec un mutex, par exemple) a les plus grandes libertés, et est donc potentiellement le plus rapide. Un algorithme sans attente à l'autre extrême doit utiliser des opérations atomiques à chaque étape, ce qui peut être beaucoup plus lent.

L'obtention d'un verrou est en fait plutôt bon marché, vous ne devriez donc jamais vous en soucier sans une compréhension approfondie du sujet. De plus, les algorithmes de blocage avec des mutex sont beaucoup plus faciles à lire, à écrire et à raisonner. En revanche, même les structures de données sans verrouillage les plus simples sont le résultat de longues recherches ciblées, chacune d'entre elles valant un ou plusieurs doctorats.

En un mot, les algorithmes sans verrouillage ou sans attente échangent la pire latence contre la latence et le débit moyens. Tout est plus lent, mais rien n'est jamais très lent. Il s'agit d'une caractéristique très spéciale qui n'est utile que dans des situations très spécifiques (comme les systèmes en temps réel).

53
Kerrek SB

Un verrou a tendance à nécessiter plus d'opérations qu'une simple opération atomique. Dans les cas les plus simples, memory_order_seq_cst sera environ deux fois plus rapide que le verrouillage car le verrouillage a tendance à exiger, au minimum deux opérations atomiques dans son implémentation (une pour verrouiller, une pour déverrouiller). Dans de nombreux cas, il en faut encore plus. Cependant, une fois que vous commencez à tirer parti des commandes de mémoire, cela peut être beaucoup plus rapide car vous êtes prêt à accepter moins de synchronisation.

De plus, vous verrez souvent que "les algorithmes de verrouillage sont toujours aussi rapides que les algorithmes sans verrouillage". C'est un peu vrai. L'idée de base est que si l'algorithme le plus rapide se trouve être sans verrouillage, alors l'algorithme le plus rapide sans la garantie sans verrouillage est AUSSI le même algorithme! Cependant, si l'algortihm le plus rapide nécessite des verrous, alors ces garanties exigeantes sans verrouillage doivent trouver un algorithme plus lent.

En général, vous verrez des algorithmes sans verrouillage dans quelques algorithmes de bas niveau, où les performances de l'exploitation des opcodes spécialisés sont utiles. Dans presque tous les autres codes, le verrouillage est une performance plus que satisfaisante et beaucoup plus facile à lire.

2
Cort Ammon