2012-11-08 14 views
9

Próbuję obliczyć średnią z macierzy 2d za pomocą OpenMP. Ta matryca 2d jest w rzeczywistości obrazem.Redukcja za pomocą OpenMP

Wykonuję podział danych według wątków. Na przykład, jeśli mam N wątków niż przetwarzam liczbę wierszy/N wierszy z wątkiem0 i tak dalej.

Moje pytanie brzmi: czy mogę użyć klauzuli o redukcji OpenMP z "#pragma omp parallel"? Coś

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

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

Odpowiedz

14

Tak, można - klauzula ograniczenie ma zastosowanie do całego regionu, jak również równolegle do indywidualnych for Worksharing konstruktów. Pozwala to na np. Redukcję w obliczeń wykonanych w różnych sekcjach równoległych (preferowany sposób restrukturyzacji kodu)

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

Można również użyć OpenMP for podziału pracy konstrukt automatycznego rozprowadzania iteracji pętli między gwintu w zespole zamiast reimplementing go przy użyciu sekcje:

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

pamiętać, że zmienne są prywatne i zmniejszenie ich wartości pośrednie (czyli wartości trzymają przed redukcją na koniec regionu parallel) są tylko częściowo i niezbyt użyteczne. Przykładowo, następną pętlę seryjny nie może być (łatwo?) Przekształca się równolegle jedna z operacji redukcyjnej

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

Tutaj yada yada code powinny być wykonywane w każdej iteracji, gdy skumulowana wartość sum przeszedł wartość threshold. Gdy pętla działa równolegle, prywatne wartości sum mogą nigdy nie osiągnąć threshold, nawet jeśli ich suma się uda.

+0

Jeśli dzwoni zamówiony z tego rodzaju dystrybucją, traci większość paralelizmu. – dreamcrash

+1

@dreamcrash, jeśli jest poprawnie zaimplementowany, wykonanie polecenia może nie zabić większości paralelizmu - patrz [ta odpowiedź] (http://stackoverflow.com/a/13230816/1374437). –

+0

Dokładnie, nie możemy używać statycznego dla domyślnego rozmiaru porcji. – dreamcrash

0

w swoim przypadku sum = sum + val może interpretować jako val[i] = val[i-1] + val[i] w tablicy 1-D (albo val[rows][cols] = val[rows][cols-1] + val[rows][cols] w tablicy 2-d), który jest obliczenie prefix sum.

Redukcja jest jednym z rozwiązań dla sumy prefiksów, możesz użyć redukcji dla dowolnych komutatywnych operatorów, takich jak "+", "-", "*", "/".

+0

W jaki sposób '-' i'/'komutatywne-asocjacyjne? –