Cómo: Convertir un bucle OpenMP que usa una variable de reducción para usar el Runtime de simultaneidad

En este ejemplo se muestra cómo convertir un bucle OpenMP paralelofor que usa la cláusula informe detallado para emplear el runtime de simultaneidad.

La cláusula OpenMP reduction permite especificar una o más variables privadas de subprocesos que están sujetas a una operación de reducción al final de la región paralela.OpenMP predefine un conjunto de operadores de reducción.Cada variable de reducción debe ser un escalar (por ejemplo, int, long y float).OpenMP también define varias restricciones sobre cómo se usan las variables de reducción en una región paralela.

La biblioteca de patrones paralelo (PPL) proporciona el concurrency::combinable (clase), que proporciona almacenamiento de información reutilizable y local de subprocesos que le permite realizar cálculos detallados y, a continuación, combinar esos cálculos en un resultado final.La clase combinable es una plantilla que actúa en los tipos escalares y complejos.Para utilizar el combinable de clases, realizar sub-computations en el cuerpo de una construcción paralelo y, a continuación, llame a la concurrency::combinable::combine o concurrency::combinable::combine_each método para generar el resultado final.Los métodos combine y combine_each toman una función de combinación que especifica cómo combinar cada par de elementos.Por consiguiente, la clase combinable no se limita a un conjunto fijo de operadores de reducción.

Ejemplo

En este ejemplo se usa OpenMP y el runtime de simultaneidad para calcular la suma de los 35 primeros números de 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);
}

Este ejemplo produce el siguiente resultado.

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.

Para obtener más información sobre la clase combinable, vea Contenedores y objetos paralelos.

Compilar el código

Copie el código de ejemplo y péguelo en un proyecto de Visual Studio o lo pega en un archivo denominado concrt-omp-fibonacci-reduction.cpp y, a continuación, ejecute el siguiente comando en una ventana de símbolo del sistema de Visual Studio.

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

Vea también

Conceptos

Migrar de OpenMP al Runtime de simultaneidad

Contenedores y objetos paralelos