Condividi tramite


Procedura: Convertire un ciclo OpenMP che usa una variabile di riduzione per l'utilizzo del runtime di concorrenza

In questo esempio viene illustrato come convertire un ciclo OpenMP parallelofor che usa la clausola di riduzione per usare il runtime di concorrenza.

La clausola OpenMP reduction consente di specificare una o più variabili private del thread soggette a un'operazione di riduzione alla fine dell'area parallela. OpenMP consente di definire un set di operatori di riduzione. Ogni variabile di riduzione deve essere scalare (ad esempio, int, longe float). OpenMP definisce anche diverse restrizioni sul modo in cui le variabili di riduzione vengono usate in un'area parallela.

La libreria PPL (Parallel Patterns Library) fornisce la classe concurrency::combinable , che fornisce un'archiviazione thread-local riutilizzabile che consente di eseguire calcoli con granularità fine e quindi unire tali calcoli in un risultato finale. La combinable classe è un modello che agisce su tipi scalari e complessi. Per usare la combinable classe , eseguire i calcoli secondari nel corpo di un costrutto parallelo e quindi chiamare il metodo concurrency::combinable::combine o concurrency::combinable::combine_each per produrre il risultato finale. I combine metodi e combine_each accettano ogni funzione di combinazione che specifica come combinare ogni coppia di elementi. Pertanto, la combinable classe non è limitata a un set fisso di operatori di riduzione.

Esempio

Questo esempio usa sia OpenMP che Il runtime di concorrenza per calcolare la somma dei primi 35 numeri di Fibonacci.

// 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);
}

Questo esempio produce il seguente output:

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.

Per altre informazioni sulla combinable classe , vedere Contenitori e oggetti paralleli.

Compilazione del codice

Copiare il codice di esempio e incollarlo in un progetto di Visual Studio oppure incollarlo in un file denominato concrt-omp-fibonacci-reduction.cpp e quindi eseguire il comando seguente in una finestra del prompt dei comandi di Visual Studio.

cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp

Vedi anche

Migrazione da OpenMP al runtime di concorrenza
Contenitori e oggetti paralleli