Qual è la differenza tra questi due?
[UN]
#pragma omp parallel
{
#pragma omp for
for(int i = 1; i < 100; ++i)
{
...
}
}
[B]
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
...
}
Qual è la differenza tra questi due?
[UN]
#pragma omp parallel
{
#pragma omp for
for(int i = 1; i < 100; ++i)
{
...
}
}
[B]
#pragma omp parallel for
for(int i = 1; i < 100; ++i)
{
...
}
Risposte:
Non credo che ci sia alcuna differenza, una è una scorciatoia per l'altra. Sebbene la tua implementazione esatta potrebbe gestirli in modo diverso.
I costrutti combinati di condivisione del lavoro parallela sono una scorciatoia per specificare un costrutto parallelo contenente un costrutto di condivisione del lavoro e nessun'altra istruzione. Le clausole ammesse sono l'unione delle clausole ammesse per i contratti paralleli e di condivisione del lavoro.
Tratto da http://www.openmp.org/mp-documents/OpenMP3.0-SummarySpec.pdf
Le specifiche per OpenMP sono qui:
Questi sono equivalenti.
#pragma omp parallel
genera un gruppo di thread, mentre #pragma omp for
divide le iterazioni del ciclo tra i thread generati. Puoi fare entrambe le cose contemporaneamente con la #pragma omp parallel for
direttiva fused .
#pragma omp parallel for
direttiva. Ci dovrebbe essere qualche differenza.
Ecco un esempio di utilizzo di separate parallel
e for
qui . In breve, può essere utilizzato per l'allocazione dinamica di array privati di thread OpenMP prima di eseguire il for
ciclo in diversi thread. È impossibile eseguire la stessa inizializzazione nel parallel for
caso.
UPD: Nell'esempio della domanda non c'è differenza tra un singolo pragma e due pragmi. Ma in pratica puoi rendere il comportamento più sensibile ai thread con le direttive parallele e for separate. Alcuni codici per esempio:
#pragma omp parallel
{
double *data = (double*)malloc(...); // this data is thread private
#pragma omp for
for(1...100) // first parallelized cycle
{
}
#pragma omp single
{} // make some single thread processing
#pragma omp for // second parallelized cycle
for(1...100)
{
}
#pragma omp single
{} // make some single thread processing again
free(data); // free thread private data
}
Sebbene entrambe le versioni dell'esempio specifico siano equivalenti, come già menzionato nelle altre risposte, c'è ancora una piccola differenza tra loro. La prima versione include una barriera implicita non necessaria, riscontrata alla fine di "omp for". L'altra barriera implicita si trova alla fine della regione parallela. Aggiungere "nowait" a "omp for" renderebbe i due codici equivalenti, almeno dal punto di vista di OpenMP. Dico questo perché un compilatore OpenMP potrebbe generare codice leggermente diverso per i due casi.
Vedo tempi di esecuzione nettamente diversi quando prendo un ciclo for in g ++ 4.7.0 e utilizzo
std::vector<double> x;
std::vector<double> y;
std::vector<double> prod;
for (int i = 0; i < 5000000; i++)
{
double r1 = ((double)rand() / double(RAND_MAX)) * 5;
double r2 = ((double)rand() / double(RAND_MAX)) * 5;
x.push_back(r1);
y.push_back(r2);
}
int sz = x.size();
#pragma omp parallel for
for (int i = 0; i< sz; i++)
prod[i] = x[i] * y[i];
il codice seriale (no openmp
) viene eseguito in 79 ms. il codice "parallelo per" viene eseguito in 29 ms. Se ometto for
e uso #pragma omp parallel
, il runtime arriva fino a 179 ms, che è più lento del codice seriale. (la macchina ha una concorrenza hardware di 8)
il codice si collega a libgomp
#pragma omp for
non c'è alcuna condivisione multi-thread del ciclo. Ma non era comunque il caso degli OP, riprova con un ulteriore #pragma omp for
all'interno di #pragm omp parallel
e dovrebbe funzionare in modo simile (se non lo stesso) come la #pragma omp parallel for
versione.
Ci sono ovviamente molte risposte, ma questa risponde molto bene (con la fonte)
#pragma omp for
delega solo parti del ciclo per thread diversi nel team corrente. Una squadra è il gruppo di thread che eseguono il programma. All'inizio del programma, il team è composto da un solo membro: il thread principale che esegue il programma.Per creare un nuovo team di thread, è necessario specificare la parola chiave parallela. Può essere specificato nel contesto circostante:
#pragma omp parallel { #pragma omp for for(int n = 0; n < 10; ++n) printf(" %d", n); }
e:
Cosa sono: parallelo, per e una squadra
La differenza tra parallel, parallel for e for è la seguente:
Un team è il gruppo di thread che vengono eseguiti attualmente. All'inizio del programma, il team è costituito da un unico thread. Un costrutto parallelo divide il thread corrente in un nuovo team di thread per la durata del blocco / istruzione successivo, dopodiché il team si fonde di nuovo in uno solo. for divide il lavoro del ciclo for tra i thread del team attuale.
Non crea thread, divide solo il lavoro tra i thread del team attualmente in esecuzione. parallel for è un'abbreviazione per due comandi contemporaneamente: parallel e for. Parallel crea una nuova squadra e per le divisioni quella squadra gestisce diverse parti del ciclo. Se il tuo programma non contiene mai un costrutto parallelo, non c'è mai più di un thread; il thread principale che avvia il programma e lo esegue, come nei programmi non threading.
schedule(static, chunk)
clausola per la direttiva, ottengo un problema. Il codice funziona bene, ma quando richiamo questo codice da un programma MPI, viene eseguito in un ciclo infinito. Il contatore del ciclo è zero in tutte le iterazioni di questo ciclo. Ho il contatore del ciclo definito come privato nella#pragma omp parallel
direttiva. Non ho idea del motivo per cui fallisce solo quando MPI richiama il codice. Sono in qualche modo sicuro che ogni processo MPI sia in esecuzione su un processore diverso del cluster, se ciò è importante. Non ho idea se la pianificazione sta causando il problema.