Question

Sur Internet, on trouve de nombreux débats sur l'utilisation de volatile mot-clé en programmation parallèle, avec parfois une argumentation contradictoire.

L'une des discussions les plus fiables sur ce sujet semble être cet article de Arch Robison.L'exemple qu'il utilise est la tâche consistant à transmettre une valeur d'un thread à un autre :

Sujet 1.calcule un produit matriciel et le donne au Thread 2, qui en fait autre chose.La matrice est variable M et le drapeau est un volatile aiguille R.

  1. Le thread 1 multiplie calcule un produit matriciel M et définit atomiquement R pour pointer vers M.
  2. Le thread 2 attend que R!=NULL puis utilise M comme facteur pour calculer un autre produit matriciel.

En d’autres termes, M est un message et R est un indicateur prêt.

L'auteur affirme que même si déclarer R comme volatile résoudra le problème de propagation du changement du thread 1 au thread 2, il ne garantit pas quelle sera la valeur de M lorsque cela se produira.Et les missions à R et M peut être récommandé.Nous devons donc faire les deux M et R volatile ou utilisez un mécanisme de synchronisation dans une bibliothèque comme pthreads.

Ma question est, comment faire ce qui suit en C

1) Comment partager un seul indicateur entre deux threads - Comment lui attribuer atomiquement, assurez-vous que l'autre thread verra le changement et testera le changement dans l'autre thread.L’utilisation de volatile est-elle légitime dans ce cas ?Ou une bibliothèque peut-elle fournir un moyen conceptuellement meilleur ou plus rapide, impliquant probablement des barrières de mémoire ?

2) Comment bien faire l'exemple de Robison, alors comment envoyer la matrice M d'un thread à l'autre et le faire en toute sécurité (et de préférence de manière portable avec pthreads)

Était-ce utile?

La solution

"volatile" est une indication pour le compilateur de ne pas optimiser l'accès à la mémoire, c'est-à-dire de ne pas supposer qu'une valeur en mémoire est inchangée depuis la dernière écriture (locale).Sans cet indice, un compilateur pourrait supposer qu'une valeur d'un registre à partir duquel la variable est copiée est toujours valide.Ainsi, même s’il est plutôt improbable qu’une matrice soit conservée dans un registre, en général les deux variables devraient être volatiles, ou plus précisément, volatiles pour le récepteur.

Dans le multithreading réel, on préfère utiliser un sémaphore ou quelque chose comme ça pour la signalisation, évitant ainsi d'attendre le récepteur.

Autres conseils

Sous des architectures comme x86, une variable correctement alignée (et dimensionnée) comme un pointeur sera par défaut lue et écrite de manière atomique, mais ce qui doit se produire est une sérialisation des lectures/écritures de la mémoire pour empêcher la réorganisation dans le pipeline du processeur (via l'utilisation d'une barrière mémoire explicite ou d'une opération de verrouillage de bus) ainsi que l'utilisation de volatile pour empêcher le compilateur de réorganiser le code qu'il génère.

Le moyen le plus simple de procéder consiste à utiliser CAS.la plupart des éléments intrinsèques CAS fournissent une barrière de mémoire complète au niveau du compilateur et du bus mémoire du processeur.sous MSVC, vous pouvez utiliser le Interlock* les fonctions, BTS, BTR, Inc, Dec, Exchange et Add fonctionneraient toutes pour un indicateur, pour GCC, vous utiliseriez le __sync_* variantes basées.

Pour des options plus portables, vous pouvez utiliser un pthread_mutex ou pthread_cond.si tu peux utiliser C11 vous pouvez également consulter le _Atomic mot-clé.

La méthode « classique » consiste pour le thread 1 à pousser le pointeur vers la matrice allouée dynamiquement sur une file d'attente producteur-consommateur sur laquelle le thread 2 attend.Une fois poussé, le thread 1 peut allouer un autre M et commencer à travailler dessus, s'il le souhaite.

Jouer avec des drapeaux volatils, etc.car une optimisation peut être prématurée si les performances globales sont dominées par des opérations sur de grandes matrices.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top