Delen via


Hoe te doen: Een OpenMP-lus converteren die gebruikmaakt van een reductievariabele om de gelijktijdigheidsruntime te gebruiken

In dit voorbeeld wordt gedemonstreerd hoe u een OpenMP-parallel-for-lus die de reductieclausule gebruikt, kunt omzetten naar gebruik van het concurrency runtime.

Met de OpenMP-component reduction kunt u een of meer thread-privévariabelen opgeven waarvoor een reductiebewerking aan het einde van de parallelle regio wordt uitgevoerd. OpenMP definieert een set reductieoperators. Elke reductievariabele moet een scalaire waarde zijn (bijvoorbeeld int, longen float). OpenMP definieert ook verschillende beperkingen voor het gebruik van reductievariabelen in een parallelle regio.

De PPL (Parallel Patterns Library) biedt de gelijktijdigheid::combinatiebare klasse, die herbruikbare, thread-lokale opslag biedt waarmee u verfijnde berekeningen kunt uitvoeren en deze berekeningen vervolgens kunt samenvoegen tot een eindresultaat. De combinable klasse is een sjabloon die werkt op zowel scalaire als complexe typen. Als u de combinable klasse wilt gebruiken, voert u subberekeningen uit in de hoofdtekst van een parallelle constructie en roept u de concurrency::combinable::combine of concurrency::combinable::combine_each methode aan om het uiteindelijke resultaat te produceren. De combine en combine_each methoden nemen elk een combinatiefunctie die aangeeft hoe elk paar elementen moet worden gecombineerd. Daarom is de combinable klasse niet beperkt tot een vaste set reductieoperators.

Voorbeeld

In dit voorbeeld worden zowel OpenMP als de Gelijktijdigheidsruntime gebruikt om de som van de eerste 35 Fibonacci-getallen te berekenen.

// concrt-omp-fibonacci-reduction.cpp
// compile with: /EHsc /openmp
#include <ppl.h>
#include <iostream>

using namespace concurrency;
using namespace std;

// Computes the nth Fibonacci number.
// This function illustrates a lengthy operation and is therefore
// not optimized for performance.
int fibonacci(int n)
{
   if (n < 2)
      return n;

   // Compute the components in parallel.
   int n1, n2;
   parallel_invoke(
      [n,&n1] { n1 = fibonacci(n-1); },
      [n,&n2] { n2 = fibonacci(n-2); }
   );

   return n1 + n2;
}

// Uses OpenMP to compute the sum of Fibonacci numbers in parallel.
void omp_parallel_fibonacci_sum(int count)
{
   int sum = 0;
   #pragma omp parallel for reduction(+ : sum)
      for (int i = 0; i < count; ++i)
      {
         sum += fibonacci(i);
      }

   wcout << L"The sum of the first " << count << L" Fibonacci numbers is " 
         << sum << L'.' << endl;
}

// Uses the Concurrency Runtime to compute the sum of Fibonacci numbers in parallel.
void concrt_parallel_fibonacci_sum(int count) 
{
   combinable<int> sums;
   parallel_for(0, count, [&sums](int i)
      {
         sums.local() += fibonacci(i);
      });

   wcout << L"The sum of the first " << count << L" Fibonacci numbers is " 
         << sums.combine(plus<int>()) << L'.' << endl;
}

int wmain()
{
   const int count = 35;

   wcout << L"Using OpenMP..." << endl;
   omp_parallel_fibonacci_sum(count);

   wcout << L"Using the Concurrency Runtime..." << endl;
   concrt_parallel_fibonacci_sum(count);
}

In dit voorbeeld wordt de volgende uitvoer geproduceerd.

Using OpenMP...
The sum of the first 35 Fibonacci numbers is 14930351.
Using the Concurrency Runtime...
The sum of the first 35 Fibonacci numbers is 14930351.

Zie combinable voor meer informatie over de klasse.

De code compileren

Kopieer de voorbeeldcode en plak deze in een Visual Studio-project, of plak deze in een bestand met de naam concrt-omp-fibonacci-reduction.cpp en voer vervolgens de volgende opdracht uit in een Visual Studio-opdrachtpromptvenster.

cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp

Zie ook

Migreren van OpenMP naar de Gelijktijdigheidsruntime
parallelle containers en objecten