2.7.2.6 zmniejszenie
Ta klauzula wykonuje zmniejszenia na zmienne skalarne, które pojawiają się w Zmienna listy, z op operatora.Składnia reduction klauzuli jest w następujący sposób:
reduction(op:variable-list)
Zmniejszenie jest zwykle określana dla instrukcji z jedną z następujących form:
x = x op expr
x binop= expr
x = expr op x (except for subtraction)
x++
++x
x--
--x
w przypadku gdy:
x
Jednej ze zmiennych obniżki określone w list.Lista zmiennych
Rozdzielana przecinkami lista zmienne skalarne redukcji.wyrażenie
Wyrażenie typu skalarne nie odwołuje się do x.op
Przeciążony operator not, ale jedna z +, *, - &, ^, |, & &, lub ||.binop
Przeciążony operator not, ale jedna z +, *, - &, ^, lub.
Oto przykład z reduction klauzuli:
#pragma omp parallel for reduction(+: a, y) reduction(||: am)
for (i=0; i<n; i++) {
a += b[i];
y = sum(y, c[i]);
am = am || b[i] == c[i];
}
Jak pokazano w przykładzie, operator może być ukryte wewnątrz wywołania funkcji.Użytkownika należy zachować ostrożność, aby podmiot gospodarczy określone w reduction klauzuli pasuje do operacji redukcji.
Chociaż prawy operand || operator nie ma żadnych efektów ubocznych w tym przykładzie, są dozwolone, ale powinny być używane z rozwagą.W tym kontekście efekt uboczny, który gwarantuje, że nie występują podczas sekwencyjne wykonanie pętli może wystąpić podczas przetwarzania równoległego.Różnica ta może wystąpić, ponieważ kolejność wykonywania iteracji jest nieokreślony.
Operator jest używana do określenia wartości początkowej dowolne zmienne prywatne używane przez kompilator redukcji i określenia operator prawdopodobnej.Jawnie określając operatora pozwala instrukcji zmniejszenie się poza zakres leksykalne konstrukcji.Dowolna liczba reduction klauzul mogą być określone w dyrektywie, ale zmienna może pojawić się w co najwyżej jeden reduction klauzuli do tej dyrektywy.
Prywatną kopię każdej zmiennej w listy zmiennej jest tworzony, jeden dla każdego wątku tak, jakby private wykorzystano klauzuli.Prywatnej kopii jest inicjowany zgodnie z operatora (patrz poniższa tabela).
Na koniec regionu, dla którego reduction określono klauzuli, oryginalny obiekt jest aktualizowany w celu odzwierciedlenia wynikiem połączenia pierwotną wartość z końcowej każdego prywatnej kopii za pomocą operatora określone.Operatorzy redukcji są wszystkie asocjacyjną (z wyjątkiem dla odejmowania) i kompilator może swobodnie ponownie skojarzyć przy obliczaniu wartości końcowej.(Wyniki częściowe zmniejszenie odejmowania są dodawane do formularza wartość końcową).
Wartość oryginalny obiekt staje się nieokreślone, gdy pierwszy wątek osiągnie zawierające klauzulę i pozostaje tak, aż do obliczeń redukcji.Normalnie przy obliczaniu zostanie ukończona na końcu konstrukcji; Jednakże jeśli reduction na konstrukcji, do której jest używana klauzula nowait jest również stosowane, wartość oryginalny obiekt pozostaje nieokreślona, dopóki synchronizację bariery przeprowadzono w celu zapewnienia, że zakończono wszystkie wątki reduction klauzuli.
Poniższa lista zawiera podmioty gospodarcze, które są prawidłowe i ich wartości kanoniczny inicjalizacji.Wartości rzeczywiste inicjowania będzie zgodny z typem danych zmiennej redukcji.
Operator |
Inicjowanie |
---|---|
+ |
0 |
* |
1 |
- |
0 |
& |
~0 |
| |
0 |
^ |
0 |
& & |
1 |
|| |
0 |
Ograniczenia w odniesieniu do reduction klauzuli są w następujący sposób:
Typ zmienne w reduction klauzuli musi być prawidłowa dla operatora redukcji, z wyjątkiem, że nigdy nie są dozwolone typy wskaźnik i odwołania.
Zmienna, która jest określona w reduction klauzuli nie musi być const-kwalifikowaną.
Zmienne, które są prywatne w ramach równoległego regionu lub które są widoczne w reduction klauzuli równolegle dyrektywy nie może być określony w reduction klauzula w sprawie dyrektywy podziału pracy, która wiąże konstrukcja równolegle.
#pragma omp parallel private(y) { /* ERROR - private variable y cannot be specified in a reduction clause */ #pragma omp for reduction(+: y) for (i=0; i<n; i++) y += b[i]; } /* ERROR - variable x cannot be specified in both a shared and a reduction clause */ #pragma omp parallel for shared(x) reduction(+: x)