Not
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Det här exemplet visar hur du konverterar en grundläggande loop som använder OpenMP parallel och for-direktiv för att använda Concurrency Runtime concurrency::parallel_for-algoritmen.
Exempel – primtal
I det här exemplet används både OpenMP och Concurrency Runtime för att beräkna antalet primära tal i en matris med slumpmässiga värden.
// 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;
}
Det här exemplet genererar följande utdata.
Using OpenMP...
found 107254 prime numbers.
Using the Concurrency Runtime...
found 107254 prime numbers.
Algoritmen parallel_for och OpenMP 3.0 tillåter att indextypen är en signerad integraltyp eller en osignerad integraltyp. Algoritmen parallel_for ser också till att det angivna intervallet inte spiller över en signerad typ. OpenMP-versionerna 2.0 och 2.5 tillåter endast signerade integralindextyper. OpenMP validerar inte heller indexintervallet.
Den version av det här exemplet som använder Concurrency Runtime använder också ett samtidighetsobjekt::combinable-objekt i stället för atomdirektivet för att öka räknarvärdet utan att kräva synkronisering.
Mer information om parallel_for och andra parallella algoritmer finns i Parallella algoritmer. Mer information om klassen finns i combinableParallella containrar och objekt.
Exempel – använd std::array
I det här exemplet ändras det tidigare objektet så att det fungerar på ett std::array-objekt i stället för på en intern matris. Eftersom OpenMP-versionerna 2.0 och 2.5 endast tillåter signerade integralindextyper i en parallel_for konstruktion kan du inte använda iteratorer för att komma åt elementen i en C++ Standard Library-container parallellt. Det parallella mönsterbiblioteket (PPL) tillhandahåller algoritmen concurrency::p arallel_for_each , som utför uppgifter parallellt på en iterativ container, till exempel de som tillhandahålls av C++-standardbiblioteket. Den använder samma partitioneringslogik som algoritmen parallel_for använder. Algoritmen parallel_for_each liknar C++ Standard Library std::for_each-algoritmen , förutom att algoritmen parallel_for_each kör uppgifterna samtidigt.
// 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;
}
Kompilera koden
Kopiera exempelkoden och klistra in den i ett Visual Studio-projekt, eller klistra in den i en fil med namnet concrt-omp-count-primes.cpp och kör sedan följande kommando i ett Visual Studio-kommandotolkfönster.
cl.exe /EHsc /openmp concrt-omp-count-primes.cpp
Se även
Migrera från OpenMP till Concurrency Runtime
Parallella algoritmer
parallella containrar och objekt