Ich bin relativ neu zu OpenMP und ich habe einige Monte-Carlo-Code, den ich parallelisieren möchte.OpenMP - Overhead beim Erstellen und Beenden von Threads in der For-Schleife
Ich habe eine for-Schleife, die in Reihe lief werden müssen, die die new_value()
Funktion aufruft:
for(int i = 0; i < MAX_VAL; i++)
new_value();
Diese Funktion bei jedem Aufruf einer parallelen Region öffnet:
void new_value()
{
#pragma omp parallel default(shared)
{
int thread_rank = omp_get_thread_num();
#pragma omp for schedule(static)
for(int i = 0; i < N; i++)
arr[i] = update(thread_rank);
}
}
Welche funktioniert, aber es gibt eine erhebliche Menge an Overhead, der mit dem Laichen und dem Beenden von Threads verbunden ist; Ich fragte mich, ob jemand einen Weg kannte, die Threads zu spawnen (und thread_rank
zu erreichen), bevor er die Schleife betrat, ohne die Schleife zu parallelisieren?
Es gibt einige Fragen, die gleiche Sache zu fragen, aber sie sind entweder falsch oder unbeantwortet, wobei Beispiele dafür:
This question, die fragt eine ähnliche Sache und die Antwort schlägt eine parallele Region zu schaffen und dann #pragma omp single
mit auf die äußerste Schleife, aber wie 'Joe C' in den Antwortkommentaren sagte, funktioniert das nicht. Ich kann bestätigen, dass das Programm gerade hängt.
This question fragt die genaue Gleiche, aber die (unticked) Antwort ist nur die äußerste Schleife parallelisieren die Schleife 4000 * num_threads
läuft die weder, was die Fragesteller wollten noch was ich will.
Das macht sehr viel Sinn, danke für die tolle Erklärung. Ich habe eine kleine Folgefrage (wenn es Ihnen nichts ausmacht): Wie würde ich jeden Thread dazu bringen, die for-Schleife in der Art und Weise auszuführen, wie ich ursprünglich dachte, d. H. 'Num_threads * MAX_VAL' mal? – BodneyC
Tatsächlich wird 'num_threads * MAX_VAL' ausgeführt, aber aufgrund der Worksharing-Operation wird die innere Schleifeniteration nur' MAX_VAL * N' mal ausgeführt. Daher würde das Entfernen des inneren "omp for" zu einer solchen Ausführung führen, bei der der innere Schleifenkörper "num_threads * MAX_VAL * N" mal ausgeführt wird. – Zulan
Spot on, das macht Sinn. Danke noch einmal. – BodneyC