Qu'est-ce que Cohérence séquentielle ?
Modèle de cohérence mémoire le plus intuitif : les opérations de tous les cœurs s'ordonnent en une séquence unique, où celles de chaque cœur apparaissent dans l'ordre du programme.
Nom japonais: 逐次一貫性
« Cohérence séquentielle » apparaît dans 3 questions d'entraînement réparties sur 1 thèmes, dont Multicœur et synchronisation.
Domaine: Multicœur et synchronisation
Ce que garantit le modèle
La cohérence séquentielle, définie par Leslie Lamport en 1979, exige que le résultat de toute exécution soit le même que si les opérations mémoire de tous les cœurs étaient entrelacées en une seule séquence globale, les opérations de chaque cœur y apparaissant dans l'ordre du programme. Comme lorsqu'on mélange plusieurs paquets de cartes sans réordonner aucun paquet pris isolément, l'entrelacement peut être quelconque, mais tous les cœurs voient le même. Les programmeurs peuvent raisonner sur du code concurrent en imaginant que les threads s'exécutent à tour de rôle, ce qui explique qu'il soit considéré comme le modèle de cohérence mémoire le plus intuitif.
Questions fréquentes
x86 est-il séquentiellement cohérent ?
Non. x86 implémente l'ordre total des écritures (TSO), qui permet à un chargement de s'achever avant qu'une écriture antérieure vers une adresse différente ne devienne visible aux autres cœurs ; le résultat r1 = r2 = 0 du test du tampon d'écriture peut donc se produire. Une barrière comme MFENCE ou une instruction verrouillée (lock) l'empêche.
Quelle est la différence entre cohérence séquentielle et cohérence de cache ?
La cohérence de cache garantit un ordre unique et partagé des écritures pour chaque adresse prise individuellement. La cohérence séquentielle est plus forte et couvre l'ordre relatif des opérations sur toutes les adresses, sous la forme d'un entrelacement global unique qui respecte l'ordre du programme de chaque cœur.
Que signifie memory_order_seq_cst en C++ ?
C'est l'ordre par défaut des opérations std::atomic : toutes les opérations seq_cst apparaissent dans un ordre total unique, cohérent avec l'ordre du programme de chaque thread. C'est le plus simple pour raisonner, mais il peut exiger les instructions de barrière les plus coûteuses.