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-parallelfor-Schleife, in der die Verringerung-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.
Parallele Muster Library (PPL) stellt die concurrency::combinable Klasse, die wiederverwendbare, lokalen Thread-Speicher bereitstellt, mit dem Sie die abgestimmte Berechnungen durchführen und dann die Berechnungen in ein Endergebnis zusammenführen.Die combinable-Klasse ist eine Vorlage, die sowohl auf skalare als auch auf komplexe Typen angewendet wird.Verwenden der combinable Klasse, Sub-computations im Hauptteil einer parallelen Konstrukt durchführen, und rufen anschließend die Concurrency::combinable::combine oder Concurrency::combinable::combine_each -Methode, um das Endergebnis zu generieren.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:
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 Parallele Container und Objekte.
Kompilieren des Codes
Kopieren Sie den Beispielcode und fügen Sie ihn in ein Visual Studio Projekt, oder fügen Sie ihn in eine Datei mit dem Namen Concrt-Omp-Fibonacci-reduction.cpp und führen Sie den folgenden Befehl in ein Visual Studio-Eingabeaufforderungsfenster.
cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp