Quelle est la différence entre ces deux?
[UNE]
#pragma omp parallel
{
#pragma omp for
for(int i = 1; i < 100; ++i)
{
...
}
}
[B]
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
...
}
Quelle est la différence entre ces deux?
[UNE]
#pragma omp parallel
{
#pragma omp for
for(int i = 1; i < 100; ++i)
{
...
}
}
[B]
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
...
}
Réponses:
Je ne pense pas qu'il y ait de différence, l'un est un raccourci vers l'autre. Bien que votre implémentation exacte puisse les traiter différemment.
Les constructions de partage de projet parallèles combinées sont un raccourci pour spécifier une construction parallèle contenant une construction de partage de projet et aucune autre instruction. Les clauses autorisées sont l'union des clauses autorisées pour les contrats parallèles et partagés.
Tiré de http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf
Les spécifications d'OpenMP sont ici:
Celles-ci sont équivalentes.
#pragma omp parallel
génère un groupe de threads, tandis que #pragma omp for
divise les itérations de boucle entre les threads générés. Vous pouvez faire les deux choses à la fois avec la #pragma omp parallel for
directive fusionnée .
#pragma omp parallel for
directive. Il devrait y avoir une différence.
Voici un exemple d'utilisation de séparés parallel
et for
ici . En bref, il peut être utilisé pour l'allocation dynamique de tableaux privés de threads OpenMP avant d'exécuter le for
cycle dans plusieurs threads. Il est impossible de faire la même initialisation en parallel for
cas.
UPD: Dans l'exemple de question, il n'y a pas de différence entre un pragma unique et deux pragmas. Mais en pratique, vous pouvez créer un comportement plus sensible aux threads avec des directives parallèles et for séparées. Un peu de code par exemple:
#pragma omp parallel
{
double *data = (double*)malloc(...); // this data is thread private
#pragma omp for
for(1...100) // first parallelized cycle
{
}
#pragma omp single
{} // make some single thread processing
#pragma omp for // second parallelized cycle
for(1...100)
{
}
#pragma omp single
{} // make some single thread processing again
free(data); // free thread private data
}
Bien que les deux versions de l'exemple spécifique soient équivalentes, comme déjà mentionné dans les autres réponses, il y a encore une petite différence entre elles. La première version inclut une barrière implicite inutile, rencontrée à la fin du "omp for". L'autre barrière implicite se trouve à l'extrémité de la région parallèle. Ajouter "nowait" à "omp for" rendrait les deux codes équivalents, au moins du point de vue d'OpenMP. Je mentionne cela car un compilateur OpenMP pourrait générer un code légèrement différent pour les deux cas.
Je vois des temps d'exécution très différents lorsque je prends une boucle for dans g ++ 4.7.0 et que j'utilise
std::vector<double> x;
std::vector<double> y;
std::vector<double> prod;
for (int i = 0; i < 5000000; i++)
{
double r1 = ((double)rand() / double(RAND_MAX)) * 5;
double r2 = ((double)rand() / double(RAND_MAX)) * 5;
x.push_back(r1);
y.push_back(r2);
}
int sz = x.size();
#pragma omp parallel for
for (int i = 0; i< sz; i++)
prod[i] = x[i] * y[i];
le code de série (non openmp
) s'exécute en 79 ms. le code "parallèle pour" s'exécute en 29 ms. Si j'omets for
et utilise#pragma omp parallel
, le runtime atteint 179 ms, ce qui est plus lent que le code de série. (la machine a une concurrence hw de 8)
le code renvoie à libgomp
#pragma omp for
il n'y a pas du tout de partage multi-thread de la boucle. Mais ce n'était pas le cas de toute façon, essayez à nouveau avec un #pragma omp for
élément supplémentaire à l'intérieur du #pragm omp parallel
et il devrait fonctionner de manière similaire (sinon identique) à la #pragma omp parallel for
version.
Il y a évidemment plein de réponses, mais celle-ci y répond très bien (avec source)
#pragma omp for
ne délègue que des portions de la boucle pour différents threads de l' équipe actuelle. Une équipe est le groupe de threads exécutant le programme. Au démarrage du programme, l'équipe se compose d'un seul membre: le fil maître qui exécute le programme.Pour créer une nouvelle équipe de threads, vous devez spécifier le mot-clé parallel. Il peut être spécifié dans le contexte environnant:
#pragma omp parallel { #pragma omp for for(int n = 0; n < 10; ++n) printf(" %d", n); }
et:
Que sont: parallèle, pour et une équipe
La différence entre parallèle, parallèle pour et pour est la suivante:
Une équipe est le groupe de threads qui s'exécutent actuellement. Au début du programme, l'équipe se compose d'un seul thread. Une construction parallèle divise le thread actuel en une nouvelle équipe de threads pour la durée du bloc / instruction suivant, après quoi l'équipe se fond à nouveau en une seule. for divise le travail de la boucle for entre les threads de l'équipe actuelle.
Il ne crée pas de threads, il divise uniquement le travail entre les threads de l'équipe en cours d'exécution. parallel for est un raccourci pour deux commandes à la fois: parallel et for. Parallel crée une nouvelle équipe, et pour les scissions, cette équipe doit gérer différentes parties de la boucle. Si votre programme ne contient jamais de construction parallèle, il n'y a jamais plus d'un thread; le thread maître qui démarre le programme et l'exécute, comme dans les programmes sans thread.
schedule(static, chunk)
clause dans pour directive, j'obtiens un problème. Le code fonctionne bien, mais lorsque j'invoque ce code à partir d'un programme MPI, il s'exécute dans une boucle infinie. Le compteur de boucle est nul dans toutes les itérations de cette boucle. J'ai le compteur de boucle défini comme privé dans la#pragma omp parallel
directive. Je ne sais pas pourquoi il échoue uniquement lorsque MPI appelle le code. Je suis un peu sûr que chaque processus MPI fonctionne sur un processeur différent du cluster si cela compte. Aucune idée si le calendrier est à l'origine du problème.