Suche…


Bemerkungen

Alle 4 Versionen sind gültig, aber sie veranschaulichen verschiedene Aspekte einer Reduktion.

Standardmäßig muss das erste Konstrukt mit der reduction bevorzugt werden . Dies ist nur möglich, wenn einige Probleme explizit identifiziert werden, sodass möglicherweise eine der drei Alternativen untersucht wird.

Annäherung an PI Hand-Crafting der #pragma omp-Reduktion

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;

Die Threads werden in der #pragma omp-Parallele erzeugt. Jeder Thread verfügt über einen unabhängigen / privaten Thread-Bereich, in dem die teilweise Addition gespeichert wird. Die folgende Schleife wird mit #pragma omp for unter den Threads verteilt. In dieser Schleife berechnet jeder Thread seinen eigenen Thread-Bereich, und nach dieser Schleife aggregiert der Code den Bereich nacheinander atomar durch

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma atomic

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;

In diesem Beispiel führen alle Threads eine Teilmenge des Iterationszählers aus und sammeln sich atomar im Bereich der gemeinsam genutzten Variablen an, wodurch sichergestellt wird, dass keine Aktualisierungen verloren gehen. Wir können hier das #pragma-Atom verwenden, da die gegebene Operation (+ =) atomar ausgeführt werden kann, was die Lesbarkeit im Vergleich zur Verwendung des #pragma omp-kritisch vereinfacht.

Annäherung von PI unter Verwendung von Reduktionen basierend auf #pragma omp kritisch

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;

In diesem Beispiel führen alle Threads eine Teilmenge des Iterationszählers aus und sammeln sich atomar im Bereich der gemeinsam genutzten Variablen an, wodurch sichergestellt wird, dass keine Aktualisierungen verloren gehen.

Annäherung von PI mit #pragma omp Reduktionsklausel

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;

In diesem Beispiel führen alle Threads eine Teilmenge des Iterationszählers aus. Jeder Thread hat seine lokale private Kopie des Bereichs und am Ende des parallelen Bereichs wenden sie alle die Additionsoperation (+) an, um den endgültigen Wert für den Bereich zu erzeugen.



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow