Condividi tramite


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

In questo esempio viene illustrato come convertire un ciclo parallelfor di OpenMP che utilizza la clausola riduzione per utilizzare il runtime di concorrenza.

La clausola reduction di OpenMP consente di specificare una o più variabili thread-private che sono soggette a un'operazione di riduzione alla fine dell'area parallela.OpenMP predefinisce un set di operatori di riduzione.Ogni variabile di riduzione deve essere scalare, ad esempio int, long e float.OpenMP definisce inoltre diverse restrizioni sull'utilizzo delle variabili di riduzione in un'area parallela.

La libreria di modelli parallela (PPL) fornisce la concurrency::combinable classe, che fornisce riutilizzabili, thread local storage che consente di eseguire calcoli specifici e quindi unire tali calcoli in un risultato finale.La classe combinable è un modello che agisce sia sui tipi scalari che sui tipi complessi.Per utilizzare il combinable di classe, eseguire sub-computations nel corpo di un costrutto parallelo e quindi chiamare il concurrency::combinable::combine o concurrency::combinable::combine_each per produrre il risultato finale.I metodi combine e combine_each accettano ciascuno una funzione combine che specifica come combinare ogni coppia di elementi.La classe combinable non è pertanto limitata a un set prestabilito di operatori di riduzione.

Esempio

In questo esempio vengono utilizzati 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 l'output che segue.

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 ulteriori informazioni sulla classe combinable, vedere Contenitori e oggetti paralleli.

Compilazione del codice

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

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

Vedere anche

Concetti

Migrazione da OpenMP al runtime di concorrenza

Contenitori e oggetti paralleli