Zoeken…


Opmerkingen

Alle 4-versies zijn geldig, maar ze illustreren verschillende aspecten van een reductie.

Standaard moet de voorkeur worden gegeven aan het eerste construct dat de reduction . Dit is alleen als sommige problemen expliciet worden geïdentificeerd dat een van de 3 alternatieven kan worden onderzocht.

Benadering van PI met de hand vervaardigen van de #pragma omp-reductie

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;

De threads worden voortgebracht in de #pragma omp-parallel. Elke thread heeft een onafhankelijke / private thread_area waarin de gedeeltelijke toevoeging wordt opgeslagen. De volgende lus wordt verdeeld over threads met #pragma omp voor. In deze lus berekent elke thread zijn eigen thread_area en na deze lus aggregeert de code achtereenvolgens het gebied atomair door

Benadering van PI met behulp van reducties op basis van #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 dit voorbeeld voeren elke threads een subset van de iteratietelling uit en accumuleren ze atomair in het gedeelde variabele gebied, wat ervoor zorgt dat er geen verloren updates zijn. We kunnen de #pragma-atomic hier gebruiken omdat de gegeven bewerking (+ =) atomair kan worden uitgevoerd, wat de leesbaarheid vereenvoudigt in vergelijking met het gebruik van de #pragma omp critical.

Benadering van PI met behulp van verminderingen op basis van #pragma omp critical

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 dit voorbeeld voeren elke threads een subset van de iteratietelling uit en accumuleren ze atomair in het gedeelde variabele gebied, wat ervoor zorgt dat er geen verloren updates zijn.

Benadering van PI met clausule #pragma omp-reductie

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 dit voorbeeld voert elke thread een subset van de iteratietelling uit. Elke thread heeft zijn lokale privé-kopie van het gebied en aan het einde van het parallelle gebied passen ze allemaal de optelbewerking (+) toe om de uiteindelijke waarde voor het gebied te genereren.



Modified text is an extract of the original Stack Overflow Documentation
Licentie onder CC BY-SA 3.0
Niet aangesloten bij Stack Overflow