OpenMP: nowait et clauses de réduction sur le même pragma
Je suis étudiant OpenMP, et est venu à travers l'exemple suivant:
#pragma omp parallel shared(n,a,b,c,d,sum) private(i)
{
#pragma omp for nowait
for (i=0; i<n; i++)
a[i] += b[i];
#pragma omp for nowait
for (i=0; i<n; i++)
c[i] += d[i];
#pragma omp barrier
#pragma omp for nowait reduction(+:sum)
for (i=0; i<n; i++)
sum += a[i] + c[i];
} /*-- End of parallel region --*/
Dans la dernière boucle, il y a un nowait et une clause de réduction. Est-ce correct? Ne pas la clause de réduction doivent être synchronisées?
source d'informationauteur aperez
Vous devez vous connecter pour publier un commentaire.
La
nowait
s dans le deuxième et dernier tour de boucle sont un peu redondants. Le OpenMP spec mentionnenowait
avant la fin de la région, alors peut-être que cela peut rester dans le jeu.Mais la
nowait
avant la seconde boucle et de l'explicite barrière après il annuler les uns les autres.Enfin, à propos de la
shared
etprivate
clauses. Dans votre code,shared
n'a aucun effet, etprivate
simplement ne doit pas être utilisé à tous: Si vous avez besoin d'un thread-privé variable, il suffit de le déclarer à l'intérieur de la région parallèle. En particulier, vous devez déclarer les variables de boucle à l'intérieur de la boucle, pas avant.De faire
shared
utile, vous devez dire à OpenMP qu'il ne devrait pas partager quoi que ce soit par défaut. Vous devrait faire pour éviter les bugs en raison accidentellement des variables partagées. Ceci est fait en spécifiantdefault(none)
. Ce qui nous laisse avec:À certains égards, cela semble être un problème, que je déteste faire pour les gens. D'autre part, les réponses ci-dessus ne sont pas tout à fait exact, et je sens que doivent être corrigées.
D'abord, alors que dans cet exemple, les deux partagés et privés, de clauses ne sont pas nécessaires, je suis en désaccord avec Konrad qu'ils ne devraient pas être utilisés. L'un des problèmes les plus communs avec les gens de la parallélisation de code, c'est qu'ils ne prennent pas le temps de comprendre comment les variables sont utilisées. Pas de privatisation et/ou de la protection de variables partagées qui devrait être, compte le plus grand nombre de problèmes que je vois. En passant par l'exercice de l'examen de la manière dont les variables sont utilisées et de les mettre dans le bon partagé, privé, etc. les clauses de réduire considérablement le nombre de problèmes que vous avez.
Comme pour la question sur les obstacles, la première boucle peut avoir une clause nowait, car il n'y a pas d'utilisation de la valeur calculée (a) dans la deuxième boucle. La deuxième boucle peut avoir une clause nowait seulement si la valeur calculée (c) n'est pas utilisé avant les valeurs sont calculées (c'est à dire, il n'y a pas de dépendance). Dans l'exemple de code il y a un nowait sur la deuxième boucle, mais explicite barrière avant la troisième boucle. C'est très bien, depuis votre professeur a essayé de montrer l'utilisation d'une volonté explicite de la barrière - bien que laissant le nowait sur la deuxième boucle se faire de manière explicite de la barrière redondante (car il y a une barrière implicite à la fin d'une boucle).
D'autre part, la nowait sur la deuxième boucle et de l'explicite barrière de peut pas être nécessaire à tous. Avant la OpenMP V3.0 spécifications, beaucoup de gens suppose que quelque chose est vrai, qui n'a pas été précisé dans le cahier des charges. Avec OpenMP V3.0 spécifications suivantes a été ajoutée à la section 2.5.1 Boucle de Construire, le Tableau 2-1 annexe clause genre valeurs, statique (annexe):
Maintenant, dans votre exemple, aucun calendrier n'a été montré sur une des boucles, ce qui peut ou ne peut pas contenir. La raison en est, que le calendrier par défaut est définie par l'implémentation et tandis que la plupart des implémentations actuellement de définir le calendrier par défaut à être statique, il n'y a aucune garantie. Si votre professeur a mis sur un type de planification de la statique sans morceau de la taille d' sur l'ensemble des trois boucles, puis nowait pourrait être utilisé sur la première et la deuxième boucle et pas de barrière (implicites ou explicites) serait nécessaire entre la deuxième et la troisième boucle.
Nous en arrivons maintenant à la troisième boucle et votre question à propos de nowait et de la réduction. Comme Michy a souligné, OpenMP spécification permet à la fois (réduction et nowait) doit être spécifié. Cependant, il n'est pas vrai qu'aucune synchronisation n'est nécessaire pour la réduction complète. Dans l'exemple, l'implicite de la barrière (à la fin de la troisième boucle) peut être retiré à l'nowait. C'est parce que la réduction (somme) n'est pas utilisée avant l'implicite de la barrière de la région parallèle a été rencontrées.
Si vous regardez la OpenMP V3.0 spécifications, section 2.9.3.6 clause de réduction, vous trouverez les éléments suivants:
Cela signifie que si vous voulez utiliser la variable de la somme dans la région parallèle après la troisième boucle, alors vous avez besoin d'une barrière (implicites ou explicites) avant de vous en servir. Comme l'exemple se trouve maintenant, il est correct.
La OpenMP speficication dit:
Donc il peut y avoir plusieurs clauses ainsi, il peut être à la fois de la réduction et de nowait déclaration.
Il n'est pas nécessaire de synchronisation explicite dans le
reduction
clause - l'ajout de lasum
variable est synchronisé en raison dereduction(+: sum)
et précédent de la barrière des forcesa
etb
avoir des valeurs finales dans le temps dereduction
boucle. Lenowait
signifie que si le thread termine le travail dans la boucle, il n'a pas à attendre jusqu'à ce que tous les autres threads de finition de la même boucle.