Postupy: Převedení smyčky OpenMP využívající redukční proměnnou na využití modulu Concurrency Runtime
Tento příklad ukazuje, jak převést paralelněOpenMP pro smyčku, která používá klauzuli redukce k použití Concurrency Runtime.
Klauzule OpenMP reduction
umožňuje zadat jednu nebo více privátních proměnných vlákna, které podléhají operaci redukce na konci paralelní oblasti. OpenMP předdefinuje sadu operátorů redukce. Každá proměnná redukce musí být skalární (například int
, long
a float
). OpenMP také definuje několik omezení, jak se proměnné redukce používají v paralelní oblasti.
Knihovna PPL (Parallel Patterns Library) poskytuje souběžnost::combinable třída, která poskytuje opakovaně použitelné místní úložiště s vlákny, které umožňuje provádět jemně odstupňované výpočty a pak tyto výpočty sloučit do konečného výsledku. Třída combinable
je šablona, která funguje na skalárních i složitých typech. Chcete-li použít combinable
třídu, proveďte dílčí výpočty v těle paralelního konstruktoru a potom volejte concurrency::combinable::combine nebo concurrency::combinable::combine_each metoda pro vytvoření konečného výsledku. combine_each
Jednotlivé combine
metody přebírají kombinační funkci, která určuje, jak zkombinovat jednotlivé dvojice prvků. combinable
Proto není třída omezena na pevnou sadu redukčních operátorů.
Příklad
V tomto příkladu se k výpočtu součtu prvních 35 fibonacciho čísel používá OpenMP i Concurrency Runtime.
// 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);
}
Tento příklad vytvoří následující výstup.
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.
Další informace o combinable
třídě naleznete v tématu Paralelní kontejnery a objekty.
Probíhá kompilace kódu
Zkopírujte ukázkový kód a vložte ho do projektu sady Visual Studio nebo ho vložte do pojmenovaného concrt-omp-fibonacci-reduction.cpp
souboru a potom v okně příkazového řádku sady Visual Studio spusťte následující příkaz.
cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp
Viz také
Migrace z OpenMP do Concurrency Runtime
Paralelní kontejnery a objekty