OpenMP-Zeitplan (statisch) ohne Angabe einer Blockgröße: Blockgröße und Zuordnungsreihenfolge
Ich habe ein paar Fragen zu#pragma omp for schedule(static)
wobei die Blockgröße nicht angegeben ist.
Eine Möglichkeit, eine Schleife in OpenMP zu parallelisieren, besteht darin, sie manuell wie folgt auszuführen:
#pragma omp parallel
{
const int nthreads = omp_get_num_threads();
const int ithread = omp_get_thread_num();
const int start = ithread*N/nthreads;
const int finish = (ithread+1)*N/nthreads;
for(int i = start; i<finish; i++) {
//
}
}
Gibt es einen guten Grund, eine Schleife wie diese in OpenMP nicht manuell zu parallelisieren? Wenn ich die Werte mit vergleiche#pragma omp for schedule(static)
Ich sehe, dass die Blockgrößen für ein bestimmtes Gewinde nicht immer übereinstimmen, daher implementiert OpenMP (in GCC) die Blockgrößen anders als in definiertstart
undfinish
. Warum ist das?
Dasstart
undfinish
Werte, die ich definiert habe, haben mehrere praktische Eigenschaften.
Bearbeiten: Ursprünglich habe ich genau einen Block gesagt, aber nachdem ich darüber nachgedacht habe, ist es möglich, dass die Größe des Blocks Null ist, wenn die Anzahl der Threads viel größer als istN
(ithread*N/nthreads = (ithread*1)*N/nthreads
). Die Eigenschaft, die ich wirklich will, ist höchstens ein Stück.
Sind alle diese Eigenschaften bei der Verwendung garantiert#pragma omp for schedule(static)
?
Gemäß den OpenMP-Spezifikationen:
Programme, die davon abhängen, welcher Thread unter anderen Umständen eine bestimmte Iteration ausführt, sind nicht konform.
und
Verschiedene Schleifenregionen mit demselben Zeitplan und derselben Iterationszahl können, selbst wenn sie in derselben parallelen Region auftreten, die Iterationsraten unter Threads unterschiedlich verteilen. Die einzige Ausnahme ist für diestatisch Zeitplan
Zumschedule(static)
Die Spezifikation sagt:
Chunks werden den Threads im Team in der Reihenfolge der Thread-Nummer im Round-Robin-Verfahren zugewiesen.
Zusätzlich steht in der Spezifikation für `schedule (static):
Wenn kein chunk_size angegeben ist, wird der Iterationsbereich in ungefähr gleich große Chunks unterteilt und höchstens ein Chunk an jeden Thread verteilt.
Schließlich heißt es in der Spezifikation fürschedule(static)
:
Eine konforme Implementierung des statischen Zeitplans muss sicherstellen, dass die gleiche Zuweisung von logischen Iterationsnummern zu Threads in zwei Schleifenbereichen verwendet wird, wenn die folgenden Bedingungen erfüllt sind: 1) beide Schleifenbereiche haben die gleiche Anzahl von Schleifeniterationen, 2) beide Schleifen Für Regionen wurde der gleiche Wert für chunk_size angegeben, oder für beide Schleifenregionen wurde kein chunk_size angegeben. 3) Beide Schleifenregionen binden an dieselbe parallele Region.
Also wenn ich das richtig leseschedule(static)
werden die gleichen praktischen Eigenschaften haben, die ich als aufgeführt habestart
undfinish
obwohl mein Code auf Thread beruht, führt er eine bestimmte Iteration aus.Interpretiere ich das richtig? Dies scheint ein Sonderfall für zu seinschedule(static)
wenn die Blockgröße nicht angegeben ist.
Es ist einfacher zu definierenstart
undfinish
wie ich dann versucht habe die spezifikation für diesen fall zu unterbrechen.