2015-05-16 12 views
7

Quando uso cancel direttiva (dal OpenMP 4.0) per rompere circuito parallelo all'interno parallel for costrutto, GCC 5.1 mette in guardia " '#pragma OMP annullare per' 'nowait' all'interno per costrutto" per il seguente frammento.GCC 5.1 avverte annullare costrutto all'interno di `parallelo for` costruire

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

Per risolvere il problema, quando ho diviso a parallel + for costrutti, GCC accetta il codice in silenzio.

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

Ma io non so perché GCC avverte il primo caso, tuttavia, il costrutto non ha clausola di 'nowait'. OpenMP 4.0 API spec dice anche che parallel for è uguale a parallel + for costrutti.

2.10.1 Parallel Loop Construct

Description

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

Il comportamento di GCC è corretto? o qualcosa di sbagliato?

+4

Penso che GCC dovrebbe emettere un messaggio di errore migliore. Il compilatore Intel lancia: "errore: annulla per deve essere strettamente annidato in una regione per" per questo caso (che ha un po 'più senso). Sebbene 'paralleli per' e' paralleli' seguiti da un 'for' siano simili, un costrutto' cancel' consente solo una clausola ... methinks il compilatore legge la clausola seguita da un 'cancel' e controlla quale fosse il costrutto che lo racchiude, nel tuo primo esempio è un 'parallelo for' e non un' for', quindi il compilatore lancia quell'errore. Solo i miei 2 centesimi. – Sayan

+0

GCC emette un avviso, Clang non avvisa e ICC non riesce a compilare nel primo caso. Tutti e tre i compilatori compilano senza preavviso nel secondo caso. Interessante. –

+0

@Sayan, non sono sicuro del motivo per cui il messaggio di errore di ICC è migliore di quello di GCC. Intel sembra pensare che l'annullamento non sia all'interno di un ciclo for che è chiaramente. Sembra questo caso https://software.intel.com/en-us/articles/cdiag1159 che il compilatore fornisce l'errore corretto per. –

risposta

0

La mia ipotesi è che il codice

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

non equivale a

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

in quest'ultimo caso, ci sarebbero due barriere: uno alla fine del per e uno in fine della regione parallela; qualcosa di equivalente a:

#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 

ma credo che per scopo l'ottimizzazione, la compilter può tentare di rimuovere la seconda barriera unecessary e genera:

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

che è più 'ottimale', ma ha lo svantaggio di avvisare di avere nowait e cancellare mixed.

Problemi correlati