OpenMP et #pragma omp atomique
J'ai un problème avec OpenMP. MSVS compilateur me jette "pragma omp atomique a une forme incorrecte".
Je n'ai aucune idée de pourquoi.
Code: (programme nomme PI numéro à l'aide des intégrales de la méthode)
#include <stdio.h>
#include <time.h>
#include <omp.h>
long long num_steps = 1000000000;
double step;
int main(int argc, char* argv[])
{
clock_t start, stop;
double x, pi, sum=0.0;
int i;
step = 1./(double)num_steps;
start = clock();
#pragma omp parallel for
for (i=0; i<num_steps; i++)
{
x = (i + .5)*step;
#pragma omp atomic //this part contains error
sum = sum + 4.0/(1.+ x*x);
}
pi = sum*step;
stop = clock();
//some printf to show results
return 0;
}
OriginalL'auteur krzakov | 2012-12-24
Vous devez vous connecter pour publier un commentaire.
Votre programme est parfaitement correct syntaxiquement OpenMP code par le courant OpenMP normes (par exemple, il compile sans modification avec GCC 4.7.1), sauf que
x
doit être déclaréeprivate
(ce qui n'est pas syntaxique, mais plutôt une erreur sémantique). Malheureusement, Microsoft Visual C++ implémente un très vieux OpenMP spécification (2.0 à partir de Mars 2002) qui n'autorise que les énoncés suivants sont acceptables dans unatomic
construire:Versions ultérieures inclus x = x binop expr, mais MSVC est toujours bloqué à OpenMP version 2.0, même dans VS2012. Juste pour comparaison, l'actuel OpenMP version 3.1 et nous nous attendons à 4.0 à venir dans les mois suivants.
En OpenMP 2.0 de votre déclaration doit se lire:
Mais comme l'a déjà remarqué, il serait mieux (et généralement plus rapide) pour l'utilisation de la réduction:
(vous pouvez également écrire
sum += 4.0/(1.+ x*x);
)OriginalL'auteur Hristo Iliev
Essayer de changer
sum = sum + 4.0/(1.+ x*x)
àsum += 4.0/(1.+ x*x)
.Mais j'ai peur cela ne fonctionne pas trop. Vous pouvez essayer de répartir le travail comme ceci:cela devrait fonctionner,mais je ne suis pas sûr de savoir si elle répond à vos besoins.
J'ai proposé une solution à l'aide atomique..C'est la façon dont c'est expliqué dans la partie officielle du site de référence. Si le problème est résolu bon pour vous.
omp de réduction(+:somme) n'est pas correct. Il est probable ignoré par le compilateur, et vous obtenez un dangereux des données de course qui est caché par le numérique imprécision.
reduction
est une clause, il doit être appliqué à une autre directive OpenMP - leparallel for
directive dans votre cas.OriginalL'auteur NiVeR
Remplacer :
par
#pragma omp reduction(+:sum)
ou#pragma omp critical
Mais je suppose que #pragma omp réduction sera une meilleure option que vous avez sum+=Var;
Faire comme ceci:
reduction
est un partage de données clause, applicable à laparallel
directive (ou à la combinaison desparallel for
), pas une directive sur son propre.OriginalL'auteur Aizen
Vous avez probablement besoin d'un récapitulatif sur
#pragma
de plus que la véritable solution à votre problème.#pragma
sont un ensemble de non-standard, compilateur spécifique, et la plupart du temps, plate-forme/système spécifique - ce qui signifie que le comportement peut être différent sur des machines différentes avec le même système d'exploitation ou tout simplement sur des machines avec des configurations différentes - ensemble de instrunctions pour le pré-processeur.Comme conséquence un problème avec pragma peut être résolu que si vous regardez la documentation officielle pour votre compilateur pour votre plate-forme de choix, voici 2 liens.
Pour le C/C++ standard
#pragma
n'existe pas.Heureusement, OpenMP pragmas sont très bien définies dans un ensemble de documents standards et tout conforme compilateur C/C++ doit suivre exactement le même OpenMP pragma syntaxe.
OriginalL'auteur user1824407