2013-11-21 18 views
6

Attualmente sto lavorando su un calcolo matriciale con OpenMP. Ho diversi loop nel mio codice e invece su ogni loop #pragma omp parallelo per [...] (che crea tutti i thread e li distrugge subito dopo) vorrei creare tutti loro all'inizio e cancellarli alla fine del programma per evitare spese generali. voglio qualcosa di simile:Come annidare loop paralleli in un ciclo sequenziale con OpenMP

#pragma omp parallel 
{ 
    #pragma omp for[...] 
    for(...) 

    #pragma omp for[...] 
    for(...) 
} 

Il problema è che ho alcune parti quelli devono essere eseguire da un solo filo, ma in un ciclo, che contiene loop quelli devono essere eseguire in parallelo ... Questo è come appare:

//have to be execute by only one thread 
int a=0,b=0,c=0; 
for(a ; a<5 ; a++) 
{ 

    //some stuff 

    //loops which have to be parallelize 
    #pragma omp parallel for private(b,c) schedule(static) collapse(2) 
    for (b=0 ; b<8 ; b++); 
     for(c=0 ; c<10 ; c++) 
     { 
      //some other stuff 
     } 

    //end of the parallel zone 
    //stuff to be execute by only one thread 

} 

(I confini di loop sono piuttosto piccole nel mio esempio nel mio programma il numero di iterazioni può va fino 20.000 ....) una delle mie prime idea era quella di fare qualcosa di simile :

//have to be execute by only one thread 
#pragma omp parallel //creating all the threads at the beginning 
{ 
    #pragma omp master //or single 
    {   
     int a=0,b=0,c=0; 
     for(a ; a<5 ; a++) 
     { 

      //some stuff 

      //loops which have to be parallelize 
      #pragma omp for private(b,c) schedule(static) collapse(2) 
      for (b=0 ; b<8 ; b++); 
       for(c=0 ; c<10 ; c++) 
       { 
        //some other stuff 
       } 

      //end of the parallel zone 
      //stuff to be execute by only one thread 

     } 
    } 
} //deleting all the threads 

Non si compila, ottengo questo errore da gcc: "la regione di condivisione del lavoro potrebbe non essere strettamente annidata all'interno dell'area di lavoro condivisa, critica, ordinata, principale o esplicita".

So che proviene sicuramente dal nesting "sbagliato", ma non riesco a capire perché non funzioni. Devo aggiungere una barriera prima della zona parallela? Sono un po 'perso e non so come risolverlo.

Grazie in anticipo per il vostro aiuto. Saluti.

risposta

3

Nell'ultimo del codice delineate una regione parallela, all'interno di quella che utilizza una direttiva master per garantire che solo il thread master esegua un blocco e all'interno del blocco master tenti di parallelizzare un ciclo su tutti i thread. Dichiari di sapere che gli errori del compilatore derivano da un nesting errato, ma chiedi perché non funziona.

Non funziona perché la distribuzione di lavoro su più thread all'interno di una regione di codice che verrà eseguita solo da un thread non ha alcun senso.

Il tuo primo pseudo-codice è meglio, ma probabilmente si desidera estendere in questo modo:

#pragma omp parallel 
{ 
    #pragma omp for[...] 
    for(...) 

    #pragma omp single 
    { ... } 

    #pragma omp for[...] 
    for(...) 
} 

La direttiva single assicura che il blocco di codice che racchiude viene eseguito da un solo thread. A differenza della direttiva mastersingle implica anche una barriera all'uscita; è possibile modificare questo comportamento con la clausola nowait.

+0

Grazie per la risposta. Proverò a riordinare il mio codice per avere una struttura più facile da parallela. – user3014051

3

La maggior parte dei runtime di OpenMP non "crea tutti i thread e li distrugge subito dopo". I thread sono creati all'inizio della prima sezione OpenMP e distrutti al termine del programma (almeno questo è l'implementazione OpenMP di Intel). Non c'è alcun vantaggio in termini di prestazioni dall'utilizzo di una grande area parallela anziché di una più piccola.

I runtime di Intel (che è open source e possono essere trovati here) hanno opzioni per controllare quali thread fanno quando finiscono il lavoro. Di default gireranno per un po '(nel caso in cui il programma avvii immediatamente una nuova sezione parallela), quindi si metteranno a dormire. Se il sonno è attivo, ci vorrà un po 'più di tempo per avviarlo per la sezione parallela successiva, ma ciò dipende dal tempo tra le regioni, non dalla sintassi.

Problemi correlati