Gewusst wie: Konvertieren einer OpenMP-Schleife, in der eine reduction-Variable verwendet wird, zur Verwendung der Concurrency Runtime
In diesem Beispiel wird veranschaulicht, wie Eine OpenMP-Parallele für Schleife konvertiert wird, die die Reduktionsklausel für die Verwendung der Concurrency Runtime verwendet.
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 parallele Klasse ::kombinationsfähige Klasse bereit, die wiederverwendbare , threadlokale Speicher bereitstellt, mit der Sie feinkörnige Berechnungen durchführen und diese Berechnungen dann in ein Endergebnis zusammenführen können. Die combinable
-Klasse ist eine Vorlage, die sowohl auf skalare als auch auf komplexe Typen angewendet wird. Um die combinable
Klasse zu verwenden, führen Sie Unterberechnungen im Textkörper eines parallelen Konstrukts durch, und rufen Sie dann die Parallelität::combinable::combine oder concurrency::combinable::combine_each-Methode auf, um das Endergebnis zu erzielen. Die combine
einzelnen combine_each
Methoden verwenden eine Kombinationsfunktion , die angibt, wie jedes Elementpaar kombiniert werden soll. 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:
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.
Weitere Informationen zur combinable
Klasse finden Sie unter Parallel Containers and Objects.
Kompilieren des Codes
Kopieren Sie den Beispielcode, fügen Sie ihn in ein Visual Studio-Projekt ein, oder fügen Sie ihn in eine Datei ein, die benannt concrt-omp-fibonacci-reduction.cpp
ist, und führen Sie dann den folgenden Befehl in einem Visual Studio-Eingabeaufforderungsfenster aus.
cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp
Siehe auch
Migrieren von OpenMP zur Concurrency Runtime
Parallele Container und Objekte