Ho due versioni di codice che producono risultati equivalenti dove sto provando a parallelizzare solo il ciclo interno di un ciclo nidificato for
. Non sto ottenendo molta accelerazione, ma non mi aspettavo un 1-a-1 dal momento che sto provando solo a parallelizzare il ciclo interno.come evitare l'overhead di openMP nei loop nidificati
La mia domanda principale è perché queste due versioni hanno runtime simili? La seconda versione non esegue il fork dei thread solo una volta ed evita il sovraccarico di iniziare nuovi thread su ogni iterazione su i
come nella prima versione?
La prima versione del codice avvia discussioni su ogni iterazione del ciclo esterno simili:
for(i=0; i<2000000; i++){
sum = 0;
#pragma omp parallel for private(j) reduction(+:sum)
for(j=0; j<1000; j++){
sum += 1;
}
final += sum;
}
printf("final=%d\n",final/2000000);
Con questa uscita e compressione:
OMP_NUM_THREADS = 1
final=1000
real 0m5.847s
user 0m5.628s
sys 0m0.212s
OMP_NUM_THREADS = 4
final=1000
real 0m4.017s
user 0m15.612s
sys 0m0.336s
.515.053.691,36321 milioni
La seconda versione del codice inizia fili volta prima l'anello esterno e parallelizza il ciclo interno simili (?):
#pragma omp parallel private(i,j)
for(i=0; i<2000000; i++){
sum = 0;
#pragma omp barrier
#pragma omp for reduction(+:sum)
for(j=0; j<1000; j++){
sum += 1;
}
#pragma omp single
final += sum;
}
printf("final=%d\n",final/2000000);
Con questa uscita e compressione:
OMP_NUM_THREADS = 1
final=1000
real 0m5.476s
user 0m4.964s
sys 0m0.504s
OMP_NUM_THREADS = 4
final=1000
real 0m4.347s
user 0m15.984s
sys 0m1.204s
Perché i la seconda versione è più veloce della prima? Non evita il sovraccarico di iniziare discussioni su ogni iterazione del ciclo o sto facendo qualcosa di sbagliato?
Probabilmente perché l'implementazione di OpenMP ha tradotto in modo efficace la prima versione nella seconda versione. La maggior parte delle implementazioni è abbastanza intelligente da mantenere vivi i thread se vede che vengono costantemente creati all'interno di un ciclo esterno. – NoseKnowsAll
La tua seconda versione è migliore anche con i pool di thread, vedi [qui] (https://stackoverflow.com/questions/71/openmp-nested-for-loop-becomes-faster-when-having-parallel-before-outer- loop/31382775 # 31382775). –
Oh, sono sorpreso che la tua seconda versione sia più lenta. Hai compilato con l'ottimizzazione? Ho provato il tuo codice con l'ottimizzazione e senza OpenMP il ciclo interno è ottimizzato a 1000 ma con OpenMP non lo è. Probabilmente non hai compilato con l'ottimizzazione. –