Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Este exemplo demonstra como converter um loop básico que usa as diretivas parallel e for da OpenMP para usar o algoritmo concurrency::parallel_for do Concurrency Runtime.
Exemplo - contagem de números primos
Este exemplo usa OpenMP e o Concurrency Runtime para calcular a contagem de números primos em uma matriz de valores aleatórios.
// concrt-omp-count-primes.cpp
// compile with: /EHsc /openmp
#include <ppl.h>
#include <random>
#include <array>
#include <iostream>
using namespace concurrency;
using namespace std;
// Determines whether the input value is prime.
bool is_prime(int n)
{
if (n < 2)
return false;
for (int i = 2; i < n; ++i)
{
if ((n % i) == 0)
return false;
}
return true;
}
// Uses OpenMP to compute the count of prime numbers in an array.
void omp_count_primes(int* a, size_t size)
{
if (size == 0)
return;
size_t count = 0;
#pragma omp parallel for
for (int i = 0; i < static_cast<int>(size); ++i)
{
if (is_prime(a[i])) {
#pragma omp atomic
++count;
}
}
wcout << L"found " << count
<< L" prime numbers." << endl;
}
// Uses the Concurrency Runtime to compute the count of prime numbers in an array.
void concrt_count_primes(int* a, size_t size)
{
if (size == 0)
return;
combinable<size_t> counts;
parallel_for<size_t>(0, size, [&](size_t i)
{
if (is_prime(a[i])) {
counts.local()++;
}
});
wcout << L"found " << counts.combine(plus<size_t>())
<< L" prime numbers." << endl;
}
int wmain()
{
// The length of the array.
const size_t size = 1000000;
// Create an array and initialize it with random values.
int* a = new int[size];
mt19937 gen(42);
for (size_t i = 0; i < size; ++i) {
a[i] = gen();
}
// Count prime numbers by using OpenMP and the Concurrency Runtime.
wcout << L"Using OpenMP..." << endl;
omp_count_primes(a, size);
wcout << L"Using the Concurrency Runtime..." << endl;
concrt_count_primes(a, size);
delete[] a;
}
Este exemplo produz o seguinte resultado.
Using OpenMP...
found 107254 prime numbers.
Using the Concurrency Runtime...
found 107254 prime numbers.
O parallel_for algoritmo e o OpenMP 3.0 permitem que o tipo de índice seja um tipo integral assinado ou um tipo integral não assinado. O parallel_for algoritmo também garante que o intervalo especificado não transborde um tipo assinado. As versões 2.0 e 2.5 do OpenMP permitem apenas tipos de índice integral assinados. OpenMP também não valida o intervalo de índice.
A versão deste exemplo que usa o Concurrency Runtime também usa um objeto concurrency::combinable no lugar da diretiva atômica para incrementar o valor do contador sem exigir sincronização.
Para obter mais informações sobre parallel_for e outros algoritmos paralelos, consulte Algoritmos paralelos. Para obter mais informações sobre a combinable classe, consulte Contêineres e objetos paralelos.
Exemplo - use std::array
Este exemplo modifica o anterior para agir em um objeto std::array em vez de em uma matriz nativa. Como as versões 2.0 e 2.5 do OpenMP permitem tipos de índice integral assinados somente em uma parallel_for construção, você não pode usar iteradores para acessar os elementos de um contêiner de biblioteca padrão C++ em paralelo. A Biblioteca de Padrões Paralelos (PPL) fornece o algoritmo concurrency::parallel_for_each, que executa tarefas, em paralelo, num container iterativo, como os fornecidos pela Padrão da Biblioteca C++. Ele usa a mesma lógica de particionamento que o parallel_for algoritmo usa. O parallel_for_each algoritmo se assemelha ao algoritmo std::for_each da Biblioteca Padrão C++, exceto que o parallel_for_each algoritmo executa as tarefas simultaneamente.
// Uses OpenMP to compute the count of prime numbers in an
// array object.
template<size_t Size>
void omp_count_primes(const array<int, Size>& a)
{
if (a.size() == 0)
return;
size_t count = 0;
int size = static_cast<int>(a.size());
#pragma omp parallel for
for (int i = 0; i < size; ++i)
{
if (is_prime(a[i])) {
#pragma omp atomic
++count;
}
}
wcout << L"found " << count
<< L" prime numbers." << endl;
}
// Uses the Concurrency Runtime to compute the count of prime numbers in an
// array object.
template<size_t Size>
void concrt_count_primes(const array<int, Size>& a)
{
if (a.size() == 0)
return;
combinable<size_t> counts;
parallel_for_each(begin(a), end(a), [&counts](int n)
{
if (is_prime(n)) {
counts.local()++;
}
});
wcout << L"found " << counts.combine(plus<size_t>())
<< L" prime numbers." << endl;
}
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-count-primes.cpp e, em seguida, execute o seguinte comando em uma janela do prompt de comando do Visual Studio.
cl.exe /EHsc /openmp concrt-omp-count-primes.cpp
Ver também
Migrando do OpenMP para o Concurrency Runtime
Algoritmos paralelos
Contêineres e objetos paralelos