Porady: konwertowanie pętli OpenMP używającej zmiennej redukcji do korzystania ze współbieżności środowiska wykonawczego
W tym przykładzie pokazano, jak przekonwertować równoległeśrodowisko OpenMP dla pętli korzystającej z klauzuli redukcji w celu użycia środowiska uruchomieniowego współbieżności.
Klauzula OpenMP reduction
umożliwia określenie co najmniej jednej zmiennej prywatnej wątku, która podlega operacji redukcji na końcu regionu równoległego. OpenMP wstępnie określa zestaw operatorów redukcji. Każda zmienna redukcji musi być skalarna (na przykład int
, long
, i float
). OpenMP definiuje również kilka ograniczeń dotyczących sposobu użycia zmiennych redukcji w regionie równoległym.
Biblioteka wzorców równoległych (PPL) udostępnia klasę współbieżności::combinable , która zapewnia magazyn wielokrotnego użytku, wątkowo-lokalny, który umożliwia wykonywanie precyzyjnych obliczeń, a następnie scalanie tych obliczeń w końcowy wynik. Klasa combinable
jest szablonem, który działa zarówno na typach skalarnych, jak i złożonych. Aby użyć combinable
klasy, wykonaj obliczenia podrzędne w treści konstrukcji równoległej, a następnie wywołaj współbieżność::combineable::combine or concurrency::combineable::combineable::combine_each , aby wygenerować końcowy wynik. Metody combine
i combine_each
przyjmują funkcję łączenia, która określa sposób łączenia każdej pary elementów. combinable
W związku z tym klasa nie jest ograniczona do stałego zestawu operatorów redukcji.
Przykład
W tym przykładzie użyto zarówno protokołu OpenMP, jak i środowiska uruchomieniowego współbieżności, aby obliczyć sumę pierwszych 35 liczb Fibonacciego.
// 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);
}
W tym przykładzie są generowane następujące dane wyjściowe.
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.
Aby uzyskać więcej informacji na temat combinable
klasy, zobacz Parallel Containers and Objects (Kontenery równoległe i obiekty).
Kompilowanie kodu
Skopiuj przykładowy kod i wklej go w projekcie programu Visual Studio lub wklej go w pliku o nazwie concrt-omp-fibonacci-reduction.cpp
, a następnie uruchom następujące polecenie w oknie wiersza polecenia programu Visual Studio.
cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp
Zobacz też
Migrowanie z OpenMP do środowiska uruchomieniowego współbieżności
Równoległe kontenery oraz obiekty