Como converter um loop OpenMP que usa uma variável de redução para usar o tempo de execução de simultaneidade
Este exemplo demonstra como converter um loop OpenMP paralelapara que usa a cláusula de reduction para usar o tempo de execução de simultaneidade.
A cláusula OpenMP reduction permite especificar uma ou mais variáveis particulares threads que estão sujeitos a uma operação de redução no final da região paralela. OpenMP predefine um conjunto de operadores de redução. Cada variável de redução deve ser um escalar (por exemplo, int, long, e float). OpenMP também define várias restrições em como variáveis de redução são usados em uma região paralela.
A biblioteca (PPL) de padrões de paralelo fornece a classe de concurrency::combinable , que fornece reutilizável, o armazenamento de thread local que permite executar computações refinados e mesclar essas computações em um resultado final. A classe de combinable é um modelo que atue em escalar e em tipos complexos. Para usar a classe de combinable , executar computações subelemento no corpo de uma construção paralelo e chame o método de concurrency::combinable::combine ou de concurrency::combinable::combine_each para produzir o resultado final. Os métodos de combine e de combine_each cada usam uma função de combinar que especifica como combinar cada par de elementos. Consequentemente, a classe de combinable não é restrita a um conjunto fixo de operadores de redução.
Exemplo
Este exemplo usa OpenMP e o tempo de execução de simultaneidade para calcular a soma dos primeiros 35 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);
}
O exemplo produz a seguinte saída.
Para obter mais informações sobre a classe combinable, consulte Contêineres e objetos em paralelo.
Compilando o código
Copie o código de exemplo e cole-o em um projeto do Visual Studio, ou cole-o em um arquivo chamado concrt-omp-fibonacci-reduction.cpp e execute o comando a seguir em uma janela de prompt de comando do Visual Studio.
cl.exe /EHsc /openmp concrt-omp-fibonacci-reduction.cpp