2 votes

Comparaison et échange atomique OpenMP

J'ai une variable partagée s et la variable privée p à l'intérieur de la région parallèle.

Comment puis-je faire ce qui suit de manière atomique (ou au moins mieux qu'avec critical section) :

if ( p > s )
    s = p;
else
    p = s;

C'est-à-dire que je dois mettre à jour le maximum global (si le maximum local est meilleur) ou le lire, s'il a été mis à jour par un autre thread.

3voto

Hristo Iliev Points 29262

OpenMP 5.1 a introduit le compare qui permet d'effectuer des opérations de comparaison et d'échange (CAS) telles que

#pragma omp atomic compare
if (s < p) s = p;

En combinaison avec un capture clause, vous devriez être en mesure d'obtenir ce que vous voulez :

int s_cap;

// here we capture the shared variable and also update it if p is larger
#pragma omp atomic compare capture
{
   s_cap = s;
   if (s < p) s = p;
}

// update p if the captured shared value is larger
if (s_cap > p) p = s_cap;

Le seul problème ? La spécification 5.1 est très récente et, à ce jour (2020-11-27), aucun des compilateurs largement répandus, c'est-à-dire ceux disponibles sur Godbolt supporte OpenMP 5.1. Voir aquí pour une liste plus ou moins actualisée. Ajout de compare est toujours listé comme une tâche non réclamée sur la page OpenMP de Clang. GCC travaille toujours sur le support complet d'OpenMP 5.0 et le fichier trunk construit sur Godbolt ne reconnaît pas compare . Le compilateur oneAPI d'Intel peut ou non le supporter - il n'est pas disponible sur Godbolt et je n'arrive pas à le faire compiler du code OpenMP.

Votre meilleure chance pour l'instant est d'utiliser atomic capture combiné avec un CAS atomique spécifique au compilateur, éventuellement dans une boucle.

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