Was ist der Unterschied zwischen diesen beiden?
[EIN]
#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)
{
...
}
Ich glaube nicht, dass es einen Unterschied gibt, einer ist eine Abkürzung für den anderen. Obwohl Ihre genaue Implementierung möglicherweise anders damit umgeht.
Die kombinierten parallelen Worksharing-Konstrukte sind eine Verknüpfung zum Angeben eines parallelen Konstrukts, das ein Worksharing-Konstrukt und keine anderen Anweisungen enthält. Zulässige Klauseln sind die Vereinigung der Klauseln, die für die Parallel- und Worksharing-Konstruktionen zulässig sind.
Entnommen aus http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf
Die Spezifikationen für OpenMP finden Sie hier:
Diese sind gleichwertig.
#pragma omp parallel
erzeugt eine Gruppe von Threads, während #pragma omp for
Schleifeniterationen zwischen den erzeugten Threads aufgeteilt werden. Mit der fusionierten #pragma omp parallel for
Direktive können Sie beide Dinge gleichzeitig tun .
schedule(static, chunk)
Klausel in der Direktive verwende, tritt ein Problem auf. Der Code läuft gut, aber wenn ich diesen Code von einem MPI-Programm aus aufrufe, läuft er in eine Endlosschleife. Der Schleifenzähler ist in allen Iterationen dieser Schleife Null. Ich habe den Schleifenzähler in der#pragma omp parallel
Direktive als privat definiert . Keine Ahnung, warum es nur fehlschlägt, wenn MPI den Code aufruft. Ich bin mir ziemlich sicher, dass jeder MPI-Prozess auf einem anderen Prozessor des Clusters ausgeführt wird, wenn dies wichtig ist. Keine Ahnung, ob der Zeitplan das Problem verursacht.#pragma omp parallel for
Direktive verwende. Es sollte einen Unterschied geben.Hier ist ein Beispiel für die Verwendung von getrennt
parallel
undfor
hier . Kurz gesagt, es kann für die dynamische Zuweisung von OpenMP-Thread-Private-Arrays verwendet werden, bevor derfor
Zyklus in mehreren Threads ausgeführt wird. Es ist unmöglich, die gleiche Initialisierung für denparallel for
Fall durchzuführen .UPD: Im Fragenbeispiel gibt es keinen Unterschied zwischen einem einzelnen Pragma und zwei Pragmas. In der Praxis können Sie jedoch mit getrennten parallelen und für Direktiven ein Thread-bewussteres Verhalten erzielen. Ein Code zum Beispiel:
quelle
Obwohl beide Versionen des spezifischen Beispiels gleichwertig sind, wie bereits in den anderen Antworten erwähnt, gibt es immer noch einen kleinen Unterschied zwischen ihnen. Die erste Version enthält eine unnötige implizite Barriere, die am Ende des "omp for" auftritt. Die andere implizite Barriere befindet sich am Ende des Parallelbereichs. Durch Hinzufügen von "nowait" zu "omp for" würden die beiden Codes zumindest aus OpenMP-Sicht gleichwertig. Ich erwähne dies, weil ein OpenMP-Compiler für beide Fälle leicht unterschiedlichen Code generieren könnte.
quelle
Ich sehe ganz andere Laufzeiten, wenn ich in g ++ 4.7.0 eine for-Schleife nehme und benutze
Der Seriencode (nein
openmp
) läuft in 79 ms. Der Code "Parallel für" läuft in 29 ms. Wenn ich das weglassefor
und benutze#pragma omp parallel
, schießt die Laufzeit bis zu 179 ms, was langsamer als der Seriencode ist. (Die Maschine hat eine Hardware-Parallelität von 8)Der Code verlinkt auf
libgomp
quelle
#pragma omp for
keine Multithread-gemeinsame Nutzung der Schleife gibt. Aber das war sowieso nicht der Fall der OPs. Versuchen Sie es erneut mit einem zusätzlichen im#pragma omp for
Inneren#pragm omp parallel
und es sollte ähnlich (wenn nicht gleich) wie die#pragma omp parallel for
Version laufen .Es gibt offensichtlich viele Antworten, aber diese beantwortet es sehr gut (mit Quelle)
und:
https://bisqwit.iki.fi/story/howto/openmp/
quelle