Maison  >  Article  >  développement back-end  >  Pourquoi utiliser `memory_order_seq_cst` pour définir l'indicateur d'arrêt mais `memory_order_relaxed` pour le vérifier ?

Pourquoi utiliser `memory_order_seq_cst` pour définir l'indicateur d'arrêt mais `memory_order_relaxed` pour le vérifier ?

Linda Hamilton
Linda Hamiltonoriginal
2024-11-18 03:11:02304parcourir

Why use `memory_order_seq_cst` for setting the stop flag but `memory_order_relaxed` for checking it?

Pourquoi utiliser memory_order_seq_cst pour le réglage du drapeau d'arrêt, tout en vérifiant avec memory_order_relaxed ?

Dans sa discussion sur les opérations atomiques, Herb Sutter présente un exemple d'utilisation des atomes, y compris un mécanisme d'indicateur d'arrêt :

  • Un thread principal initie plusieurs threads de travail.
  • Les threads de travail vérifient en permanence l'indicateur d'arrêt :

    while (!stop.load(std::memory_order_relaxed))
    {
      // Do stuff.
    }
  • Le fil principal définit finalement stop = true avec order=seq_cst, puis rejoint les travailleurs.

Raisons pour ne pas utiliser détendu sur le fonctionnement du magasin

Bien que Herb suggère que l'utilisation de memory_order_relaxed pour vérifier l'indicateur soit acceptable en raison de problèmes de latence minimes, il n'y a aucun avantage notable en termes de performances à utiliser des ordres de mémoire plus stricts, même si la latence était une priorité.

Le raisonnement derrière ce refus l'utilisation de Relaxed sur le fonctionnement du magasin reste floue, peut-être en raison d'un oubli ou d'une préférence personnelle.

Considérations relatives à la latence

Les normes ISO C n'imposent pas de délais spécifiques pour la visibilité du magasin ou fournir des conseils sur la manière de l’influencer. Ces dispositions s'appliquent à toutes les opérations atomiques, y compris assouplies. Cependant, les implémentations sont encouragées à rendre les valeurs de stockage accessibles aux charges atomiques dans un délai raisonnable.

En pratique, la latence spécifique est déterminée par l'implémentation, les mécanismes de cohérence du cache matériel permettant généralement une visibilité en quelques dizaines de nanosecondes au mieux. scénarios de cas et intervalles inférieurs à la microseconde dans les scénarios les plus pessimistes.

Implications sur l'ordre de mémoire

Différentes commandes de mémoire pour les opérations de stockage ou de chargement n'accélèrent pas les magasins en réalité le temps, ils contrôlent simplement si les opérations ultérieures peuvent devenir globalement visibles alors que le magasin est toujours en attente.

Essentiellement, des commandes et des barrières plus fortes n'accélèrent pas absolument les événements, mais en retardent plutôt d'autres jusqu'à ce que le magasin ou le chargement soit terminé. Cela est vrai pour tous les processeurs du monde réel, qui s'efforcent de rendre les magasins visibles instantanément aux autres cœurs.

Par conséquent, l'augmentation des commandes de mémoire, comme l'utilisation de seq_cst, garantit que les modifications apportées à l'indicateur d'arrêt sont immédiatement visibles pour le travailleur. threads, garantissant un arrêt rapide. Cependant, cela n'a pas d'impact sur la latence réelle de la visibilité.

Avantages de la vérification détendue

L'utilisation de memory_order_relaxed pour l'opération de vérification présente plusieurs avantages :

  • Glots d'étranglement du parallélisme au niveau des instructions et de la mémoire réduits.
  • Réduction des frais généraux sur les architectures limitées par le parallélisme au niveau des instructions, en particulier celles présentant des barrières coûteuses.
  • Élimination du travail inutile dû aux branchements prédictions erronées sur les résultats de chargement.

Considérations supplémentaires

Herb identifie correctement que l'utilisation de relax pour le drapeau sale est également acceptable en raison de la synchronisation fournie par thread.join. Cependant, il convient de noter que dirty nécessite une atomicité pour empêcher les écritures simultanées de la même valeur, ce qui est toujours considéré comme une course aux données selon les normes ISO C.

En conclusion, l'utilisation de memory_order_seq_cst pour définir le drapeau d'arrêt garantit une visibilité sur les threads de travail, il n'y a aucun avantage en termes de performances à le faire de manière trop relâchée pour l'opération de chargement. memory_order_relaxed offre des avantages en termes de parallélisme au niveau des instructions et d'utilisation de la bande passante mémoire, ce qui en fait le choix préféré dans de tels scénarios.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn