openmp
Redukcje OpenMP
Szukaj…
Uwagi
Wszystkie 4 wersje są ważne, ale ilustrują różne aspekty redukcji.
Domyślnie pierwsza konstrukcja korzystająca z klauzuli reduction
musi być preferowana . Dzieje się tak tylko wtedy, gdy niektóre problemy są wyraźnie zidentyfikowane, że można zbadać dowolną z 3 alternatyw.
Przybliżenie ręcznego wytwarzania PI przez redukcję #pragma omp
int i;
int n = 1000000;
double area = 0;
double h = 1.0 / n;
#pragma omp parallel shared(n, h)
{
double thread_area = 0; // Private / local variable
#pragma omp for
for (i = 1; i <= n; i++)
{
double x = h * (i - 0.5);
thread_area += (4.0 / (1.0 + x*x));
}
#pragma omp atomic // Applies the reduction manually
area += thread_area; // All threads aggregate into area
}
double pi = h * area;
Wątki są spawnowane w równoległym #pragma omp. Każdy wątek będzie miał niezależny / prywatny obszar wątku, który przechowuje jego częściowe dodanie. Następująca pętla jest rozdzielana między wątki za pomocą #pragma omp for. W tej pętli każdy wątek oblicza swój własny obszar wątek, a po tej pętli kod sekwencyjnie agreguje obszar atomowo przez
Przybliżenie PI przy użyciu redukcji opartych na #pragma atomowej
double area;
double h = 1.0 / n;
#pragma omp parallel for shared(n, h, area)
for (i = 1; i <= n; i++)
{
double x = h * (i - 0.5);
#pragma atomic
area += (4.0 / (1.0 + x*x));
}
pi = h * area;
W tym przykładzie każdy wątek wykonuje podzbiór liczby iteracji i kumuluje się atomowo we wspólnym obszarze zmiennych, co zapewnia, że nie ma utraconych aktualizacji. Możemy tutaj użyć atomu #pragma, ponieważ daną operację (+ =) można wykonać atomowo, co upraszcza czytelność w porównaniu z użyciem krytycznego #pragma omp.
Przybliżenie PI przy użyciu redukcji opartych na #pragma omp krytycznym
double area;
double h = 1.0 / n;
#pragma omp parallel for shared(n, h, area)
for (i = 1; i <= n; i++)
{
double x = h * (i - 0.5);
#pragma omp critical
{
area += (4.0 / (1.0 + x*x));
}
}
double pi = h * area;
W tym przykładzie każdy wątek wykonuje podzbiór liczby iteracji i kumuluje się atomowo we wspólnym obszarze zmiennych, co zapewnia, że nie ma utraconych aktualizacji.
Przybliżenie PI przy użyciu klauzuli redukcji #pragma omp
int i;
int n = 1000000;
double area = 0;
double h = 1.0 / n;
#pragma omp parallel for shared(n, h) reduction(+:area)
for (i = 1; i <= n; i++)
{
double x = h * (i - 0.5);
area += (4.0 / (1.0 + x*x));
}
pi = h * area;
W tym przykładzie każdy wątek wykonuje podzbiór liczby iteracji. Każdy wątek ma swoją lokalną prywatną kopię obszaru, a na końcu regionu równoległego wszystkie stosują operację dodawania (+), aby wygenerować końcową wartość dla obszaru.