Sdílet prostřednictvím


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, longa 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