Sto leggendo il libro Un'introduzione alla programmazione parallela di Peter S. Pacheco. Nella Sezione 5.6.2, ha fornito un'interessante discussione sulla riduzione del sovraccarico di fork/join. Consideriamo l'algoritmo di ordinamento per trasposizione pari-dispari:Riduci overp fork/join OpenMP separando #omp parallelo e #omp per
for(phase=0; phase < n; phase++){
if(phase is even){
# pragma omp parallel for default(none) shared(n) private(i)
for(i=1; i<n; i+=2){//meat}
}
else{
# pragma omp parallel for default(none) shared(n) private(i)
for(i=1; i<n-1; i+=2){//meat}
}
}
L'autore sostiene che il codice di cui sopra ha un po 'alto fork/join in testa. Perché i fili sono biforcuti e uniti in ogni iterazione del ciclo esterno. Quindi, si propone la seguente versione:
# pragma omp parallel default(none) shared(n) private(i, phase)
for(phase=0; phase < n; phase++){
if(phase is even){
# pragma omp for
for(i=1; i<n; i+=2){//meat}
}
else{
# pragma omp for
for(i=1; i<n-1; i+=2){//meat}
}
}
Secondo gli autori, le seconde forche versione filettature prima dell'inizio ciclo esterno e riutilizzare le filettature per ciascuna iterazione, ottenendo prestazioni migliori.
Tuttavia, sono sospettoso della correttezza della seconda versione. A mio avviso, una direttiva #pragma omp parallel
avvia un gruppo di thread e consente ai thread di eseguire il seguente blocco strutturato in parallelo. In questo caso, il blocco strutturato deve essere l'intero ciclo esterno for(phase=0 ...)
. Allora, non dovrebbe essere il caso in cui l'intero ciclo esterno viene eseguito quattro volte dato che vengono utilizzati 4 fili? Cioè, se n=10
, allora 40 iterazioni verrebbero eseguite su 4 thread. Cosa c'è di sbagliato nella mia comprensione? E in che modo lo omp parallel
(senza per) gioca con il seguente ciclo for come sopra?
Risposta molto completa. – Neo1989
Sospetto, come lei afferma, che la seconda versione non sarà più efficiente. Soprattutto se 'n >> nthreads'. –
Potete indicarmi quali implementazioni OpenMP sono "intelligenti" in modo da non riunire i thread dopo ogni area parallela? – davide