2015-05-16 23 views
7

Wenn ich cancel Direktive (seit OpenMP 4.0) verwenden, um parallele Schleife innerhalb parallel for Konstrukt zu brechen, warnt GCC 5.1" #pragma omp Abbrechen für 'inside' nowait 'für Konstrukt " für das folgende Snippet.GCC 5.1 warnt Cancel Konstrukt innerhalb `parallel für` Konstrukt

const int N = 10000; 

int main() 
{ 
    #pragma omp parallel for 
    for (int i = 0; i < N; i++) { 
    #pragma omp cancel for // <-- here 
    } 
} 

http://coliru.stacked-crooked.com/a/de5c52da5a16c154

Für dieses Problem zu umgehen, wenn ich zu parallel + for Konstrukte aufgeteilt, akzeptiert GCC die leise Code.

int main() 
{ 
    #pragma omp parallel 
    #pragma omp for 
    for (int i = 0; i < N; i++) { 
    #pragma omp cancel for 
    } 
} 

Aber ich weiß nicht, warum GCC ersterem Fall warnt, doch das Konstrukt hat keine ‚nowait‘ -Klausel. OpenMP 4.0 API spec sagt auch, dass parallel for gleich parallel + for Konstrukte ist.

2.10.1 Parallel Loop Construct

Description

The semantics are identical to explicitly specifying a parallel directive immediately followed by a for directive.

Ist das Verhalten von GCC korrekt? oder etwas falsch?

+4

Ich denke, GCC sollte eine bessere Fehlermeldung ausgeben. Intel-Compiler löst aus: "Fehler: Abbrechen für muss in einer für Region eng verschachtelt werden" für diesen Fall (was ein wenig mehr Sinn macht). Obwohl 'parallel for' und' parallel' gefolgt von 'for' ähnlich sind, erlaubt ein' cancel'-Konstrukt nur eine Klausel ... ich denke, der Compiler liest die Klausel gefolgt von 'cancel' und prüft, was das einschließende Konstrukt ist. in Ihrem ersten Beispiel ist es ein 'parallel for' und kein' for', daher wirft der Compiler diesen Fehler. Nur meine 2 Cent. – Sayan

+0

GCC gibt eine Warnung aus, Clang gibt keine Warnung aus, und ICC kompiliert im ersten Fall nicht. Alle drei Compiler kompilieren im zweiten Fall ohne Warnung. Interessant. –

+0

@Sayan, ich bin mir nicht sicher, warum die ICC-Fehlermeldung besser ist als die GCC-Warnung. Intel scheint zu denken, dass der Abbruch nicht in einer for-Schleife ist, die es eindeutig ist. Es scheint wie in diesem Fall https://software.intel.com/en-us/articles/cdiag1159, für den der Compiler den richtigen Fehler gibt. –

Antwort

0

Meine Vermutung ist, dass Ihr Code

#pragma omp parallel for 
    for (int i = 0; i < N; i++) { 
    #pragma omp cancel for 
    } 

nicht gleichwertig ist

#pragma omp parallel 
    { 
    #pragma omp for 
    for (int i = 0; i < N; i++) { 
    #pragma omp cancel for 
    } 
    } //end of parallel region 

im letzteren Fall gäbe es zwei Hindernisse sein: ein am Ende des für und ein bei der Ende der parallelen Region; etwas Gleichwertiges zu:

#pragma omp parallel 
    { 
     #pragma omp for nowait 
     for (int i = 0; i < N; i++) { 
      #pragma omp cancel for 
     } 
     #pragma omp barrier 
    } // and here another implicit barrier 

aber ich denke, dass für die Optimierung Zweck kann die compilter versuchen, die zweite unecessary Barriere zu entfernen und erzeugt:

#pragma omp parallel 
    { 
     #pragma omp for nowait 
     for (int i = 0; i < N; i++) { 
      #pragma omp cancel for 
     } 
    } 

, die mehr ‚optimale‘ ist, hat aber den Nachteil, warnen darüber, jetzt zu haben und abzubrechen.

Verwandte Themen