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.

Jeder Thread erhält höchstens einen Block.Der Wertebereich für Iterationen nimmt direkt mit der Thread-Nummer zu (d. H. Für 100 Threads mit zwei Threads verarbeitet der erste Thread die Iterationen 1 bis 50 und den zweiten Thread 51 bis 100 und nicht umgekehrt).Bei zwei for-Schleifen über genau denselben Bereich wird jeder Thread über genau dieselben Iterationen ausgeführt.

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.

Antworten auf die Frage(1)

Ihre Antwort auf die Frage