Freigeben über


Gewusst wie: Konvertieren einer OpenMP-Schleife, in der eine reduction-Variable verwendet wird, zur Verwendung der Concurrency Runtime

In diesem Beispiel wird gezeigt, wie eine OpenMP-parallel for-Schleife, in der die reduction-Klausel verwendet wird, für die Verwendung der Concurrency Runtime konvertiert wird.

Mit der OpenMP-reduction-Klausel können Sie eine oder mehrere private Variablen im Thread angeben, auf die am Ende des parallelen Bereichs ein Reduzierungsvorgang angewendet wird. OpenMP enthält einen Satz vordefinierter Reduzierungsoperatoren. Jede Reduzierungsvariable muss ein Skalar sein (z. B. int, long und float). OpenMP definiert außerdem einige Einschränkungen für die Verwendung von Reduzierungsvariablen in einem parallelen Bereich.

Die Parallel Patterns Library (PPL) stellt die concurrency::combinable-Klasse bereit, die einen wiederverwendbaren lokalen Threadspeicher bietet, mit dem Sie differenzierte Berechnungen ausführen und diese dann zu einem Endergebnis zusammenführen können. Die combinable-Klasse ist eine Vorlage, die sowohl auf skalare als auch auf komplexe Typen angewendet wird. Führen Sie für die Verwendung der combinable-Klasse Unterberechnungen im Text eines parallelen Konstrukts aus, und rufen Sie dann die concurrency::combinable::combine-Methode oder die concurrency::combinable::combine_each-Methode auf, um das Endergebnis zu erzeugen. Die combine-Methode und die combine_each-Methode akzeptieren jeweils eine combine-Funktion, die angibt, wie jedes Elementpaar kombiniert wird. Daher ist die combinable-Klasse nicht auf einen festen Satz von Reduzierungsoperatoren beschränkt.

Beispiel

In diesem Beispiel wird mit OpenMP und der Concurrency Runtime die Summe der ersten 35 Fibonacci-Zahlen berechnet.

// 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);
}

Folgende Ergebnisse werden zurückgegeben:

  

Weitere Informationen über die combinable-Klasse finden Sie unter Parallele Container und Objekte.

Kompilieren des Codes

Kopieren Sie den Beispielcode, und fügen Sie ihn in ein Visual Studio-Projekt ein. Alternativ dazu können Sie ihn auch in eine Datei mit dem Namen concrt-omp-fibonacci-reduction.cpp einfügen und dann folgenden Befehl in einem Visual Studio-Eingabeaufforderungsfenster ausführen.

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

Siehe auch

Konzepte

Migrieren von OpenMP zur Concurrency Runtime

Parallele Container und Objekte