Comment : convertir une boucle OpenMP qui a recours à une variable de réduction pour utiliser le runtime d'accès concurrentiel
Cet exemple montre comment convertir une boucle parallelfor OpenMP qui utilise la clause réduction pour utiliser le runtime d'accès concurrentiel.
La clause reduction OpenMP vous permet de spécifier une ou plusieurs variables de thread privé qui sont soumises à une opération de réduction à la fin de la zone parallèle.OpenMP prédéfinit un ensemble d'opérateurs de réduction.Chaque variable de réduction doit être une variable scalaire (par exemple, int, long et float).OpenMP définit également plusieurs restrictions sur la façon dont les variables de réduction sont utilisées dans la région parallèle.
La bibliothèque de motifs parallèle (PPL) fournit la concurrency::combinable (classe), qui fournit le stockage local des threads réutilisable qui vous permet d'effectuer des calculs précis et puis fusionner ces calculs dans un résultat final.La classe combinable est un modèle qui agit sur les types scalaires et les types complexes.Pour utiliser le combinable de classe, effectuer des sub-computations dans le corps d'une construction parallèle et appelez ensuite la concurrency::combinable::combine ou concurrency::combinable::combine_each méthode pour produire le résultat final.Les méthodes combine et combine_each prennent chacune une fonction de combinaison qui spécifie comment combiner chaque paire d'éléments.Par conséquent, la classe combinable ne se limite pas à un ensemble fixe d'opérateurs de réduction.
Exemple
Cet exemple utilise OpenMP et le runtime d'accès concurrentiel pour calculer la somme des 35 premiers nombres 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);
}
Cet exemple génère la sortie suivante.
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.
Pour plus d'informations sur la classe combinable, consultez Conteneurs et objets parallèles.
Compilation du code
Copiez l'exemple de code, collez-le dans un projet Visual Studio et collez-le dans un fichier nommé concrt-omp-fibonacci-reduction.cpp , puis exécutez la commande suivante dans une fenêtre d'invite de commande Visual Studio.
cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp