2012-11-08 2 views
9

Sto provando a calcolare media di una matrice 2d utilizzando openmp. Questa matrice 2d è in realtà un'immagine.Riduzione con OpenMP

Sto facendo la divisione di dati thread-wise. Ad esempio, se ho N thread di I file/numero N di righe con thread0 e così via.

La mia domanda è possibile utilizzare la clausola di riduzione di openmp con "#pragma omp parallel"? Qualcosa come

#pragma omp parallel reduction(+ : sum) 
{ 
    if(thread == 0) 
     bla bla code 
     sum = sum + val; 

    else if(thread == 1) 
     bla bla code 
     sum = sum + val; 
} 

risposta

14

Sì, è possibile - la clausola di riduzione è applicabile a tutta la regione in parallelo, così come ai singoli for costrutti condivisione del lavoro. Ciò consente ad es. riduzione su calcoli realizzati in diverse sezioni parallele (il modo preferito di ristrutturare il codice):

#pragma omp parallel sections private(val) reduction(+:sum) 
{ 
    #pragma omp section 
    { 
     bla bla code 
     sum += val; 
    } 
    #pragma omp section 
    { 
     bla bla code 
     sum += val; 
    } 
} 

È anche possibile utilizzare l'OpenMP for worksharing costrutto di distribuire automaticamente le iterazioni del ciclo tra i fili nella squadra invece reimplementando utilizzando sezioni:

#pragma omp parallel for private(val) reduction(+:sum) 
for (row = 0; row < Rows; row++) 
{ 
    bla bla code 
    sum += val; 
} 

nota che le variabili di riduzione sono private ei loro valori intermedi (cioè il valore tengono prima della riduzione alla fine della regione parallel) sono solo parziali e non molto utile. Ad esempio il seguente ciclo seriale non può essere (facilmente?) Trasformato in uno parallelo con operazione di riduzione:

for (row = 0; row < Rows; row++) 
{ 
    bla bla code 
    sum += val; 
    if (sum > threshold) 
     yada yada code 
} 

Qui il yada yada code deve essere eseguito in ogni iterazione volta il valore accumulato di sum ha superato il valore di threshold. Quando il ciclo viene eseguito in parallelo, i valori privati ​​di sum potrebbero non raggiungere mai threshold, anche se la loro somma lo fa.

+0

Se egli chiama ordinato con quel tipo di distribuzione, perde la maggior parte del parallelismo. – dreamcrash

+1

@dreamcrash, se implementato correttamente, l'esecuzione ordinata potrebbe non uccidere la maggior parte del parallelismo - si veda [questa risposta] (http://stackoverflow.com/a/13230816/1374437). –

+0

Esattamente, non dobbiamo usare la statica con la dimensione del blocco predefinito. – dreamcrash

0

Nel suo caso, il sum = sum + val potrebbe interpretato come val[i] = val[i-1] + val[i] in 1-d array (o val[rows][cols] = val[rows][cols-1] + val[rows][cols] in 2-d array), che è un calcolo prefix sum.

La riduzione è una soluzione per la somma di prefisso, è possibile utilizzare la riduzione per qualsiasi operatore associativo-commutativo come '+', '-', '*', '/'.

+0

In che modo '-' e'/'commutativo-associativo? –