Ich habe eine große Schleife, die Daten generiert. Jede Iteration dauert beispielsweise 1 Sekunde und erzeugt einen Datenblock. Ich brauche alle Stücke in der richtigen Reihenfolge in die Datei geschrieben.OpenMP-Synchronisation innerhalb der Schleife
Wenn ich nur die Schleife parallelisieren wollte, könnte ich so etwas wie dies (stark vereinfacht) schreiben:
FILE* f = fopen("output.txt", "w");
omp_lock_t lock;
omp_init_lock(&lock);
int nIterations = 1000000;
#pragma omp parallel for
for(int thread=0; thread<4; thread++)
{
int a=0, b=0, c=0;
for(int n=thread; n<nIterations; n+=4)
{
int value = do_computations(&a, &b, &c);
omp_set_lock(&lock);
fprintf(f, "%d\n", value);
omp_unset_lock(&lock);
}
}
#pragma omp barrier
fclose(f);
omp_destroy_lock(&lock);
Das ist meine Ausgabe in die Datei bekommt, aber die Reihenfolge der Einträge nicht garantiert werden.
Ich möchte die Ausführung synchronisieren, so dass alle Threads ihre Aufgaben ausführen, dann der Master-Thread in die Datei schreibt und dann Threads fortsetzen. Mit anderen Worten, würde ich so etwas wie dies mag:
#pragma omp parallel for
for(int thread=0; thread<4; thread++)
{
int a=0, b=0, c=0;
int values[4];
for(int n=thread; n<nIterations; n+=4)
{
values[n] = do_computations(&a, &b, &c);
#pragma omp barrier
if(thread == 0)
{
for(int i=0; i<4; i++)
fprintf(f, "%d\n", values[i]);
}
#pragma omp barrier
}
}
#pragma omp barrier
Außer aus unerklärlichen Gründen, dies durch die OpenMP-Spezifikation ist verboten.
Oder ich könnte
#pragma omp parallel for
for(int thread=0; thread<4; thread++)
{
int a=0, b=0, c=0;
for(int n=thread; n<nIterations; n+=4)
{
int value = do_computations(&a, &b, &c);
#pragma omp ordered
{
fprintf(f, "%d\n", value);
}
}
}
#pragma omp barrier
fclose(f);
versuchen Aber das wird auch nicht funktionieren, weil „eine Iteration einer Schleife mit einem für Konstrukt ... darf nicht mehr als eine geordnete Richtlinie auszuführen.“
Ich möchte den Code nicht als einzelne Schleife umschreiben und ich möchte keine Schleifen austauschen.
Gibt es einen sauberen Weg, dies mit OpenMP zu tun, ohne andere Threading/Synchronisationstools?
In welcher Architektur/in welchem Betriebssystem läuft der Code? – Raj
Kannst du '#pragma omp parallel' statt' parallel für' verwenden? – Raj
Ist 'do_computations' wirklich drei' 0's? Ich nehme an, 'do_computations' ist keine reine Funktion (d. H. Es hat Nebenwirkungen). Wenn ja, was sind die Nebenwirkungen von 'do_computations'? Was passiert, wenn zwei Aufrufe von 'do_computations' parallel ausgeführt werden? Ich bezweifle stark, dass es sogar möglich ist, sie parallel auszuführen (basierend auf der Annahme, dass es Nebenwirkungen gibt und daher die Reihenfolge, in der die Exekutionen stattfinden * wichtig ist *). - Oder vereinfachst du den Code zu sehr? Vielleicht solltest du etwas teilen, das deine echte Schleife besser repräsentiert? – ArjunShankar