5 votes

un ordre détendu comme signal

Disons que nous avons deux fils. Un qui donne un "go" et un qui attend un "go" pour produire quelque chose.

Ce code est-il correct ou puis-je avoir une "boucle infinie" à cause du cache ou quelque chose comme ça ?

std::atomic_bool canGo{false};

void producer() {
    while(canGo.load(memory_order_relaxed) == false);
    produce_data();
}

void launcher() {
    canGo.store(true, memory_order_relaxed);
}

int main() {
    thread a{producer};
    thread b{launcher};
}

Si ce code n'est pas correct, existe-t-il un moyen de vider / invalider le cache en c++ standard ?

5voto

ThorX89 Points 967

Un signal de départ comme celui-ci sera généralement en réponse à certains changements de mémoire que vous voudrez que la cible voie.

En d'autres termes, vous voudrez généralement donner libérer / acquérir sémantique à cette signalisation.

Cela peut être fait soit en utilisant memory_order_release sur le magasin et memory_order_acquire sur la charge, ou en mettant un libérer clôture antes de le magasin détendu et et un acquérir clôture après le chargement relaxé afin que les opérations de mémoire effectuées par le signaleur avant le stockage soient visibles par le signataire (voir par exemple, https://preshing.com/20120913/acquire-and-release-semantics/ ou la norme C/C++).


La façon dont je me souviens de l'ordre des clôtures est que, d'après ce que je comprends, les opérations de mémoire partagée entre les cœurs sont effectivement IO tamponnée implémentée matériellement qui suit un protocole, et une clôture de libération devrait en quelque sorte être comme un vidage de tampon de sortie et une clôture d'acquisition comme un vidage/synchronisation de tampon d'entrée.

Maintenant, si vous videz le tampon de sortie de la mémoire de votre noyau antes de en émettant un stockage relaxé, alors lorsque le noyau cible voit le stockage relaxé, les messages d'opération de mémoire précédents doivent être disponibles pour lui et tout ce dont il a besoin pour voir ces changements de mémoire dans sa mémoire est de les synchroniser avec une clôture d'acquisition après avoir vu le stockage de signalisation.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X