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.



Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow