Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
Ez a példa bemutatja, hogyan alakíthat át egy alapszintű hurkot, amely az OpenMP parallel és for direktíváit használja, hogy a Concurrency Runtime concurrency::parallel_for algoritmust vegye igénybe.
Példa – prímszámok száma
Ez a példa az OpenMP-t és az egyidejűségi futtatókörnyezetet is használja a prímszámok számának kiszámításához véletlenszerű értékek tömbjében.
// 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;
}
Ez a példa a következő kimenetet hozza létre.
Using OpenMP...
found 107254 prime numbers.
Using the Concurrency Runtime...
found 107254 prime numbers.
Az parallel_for algoritmus és az OpenMP 3.0 lehetővé teszi, hogy az index típusa aláírt integráltípus vagy aláíratlan integráltípus legyen. Az parallel_for algoritmus gondoskodik arról is, hogy a megadott tartomány ne túlcsorduljon egy aláírt típuson. Az OpenMP 2.0-s és 2.5-ös verziói csak aláírt integrált indextípusokat engedélyeznek. Az OpenMP szintén nem ellenőrzi az indextartományt.
Az egyidejű futási környezetet használó példaverzió egy concurrency::combinable objektumot is alkalmaz az atomi direktíva helyett, hogy szinkronizáció nélkül növelje a számláló értékét.
További információ a parallel_for párhuzamos algoritmusokról és más párhuzamos algoritmusokról: Párhuzamos algoritmusok. Az osztályról további információt a combinablePárhuzamos tárolók és objektumok című témakörben talál.
Példa – az std::array használata
Ez a példa úgy módosítja az előzőt, hogy natív tömb helyett egy std::tömbobjektumon működjön. Mivel az OpenMP 2.0-s és 2.5-ös verziói csak egy parallel_for szerkezetben engedélyezik az aláírt integrált indextípusokat, nem használhat iterátorokat a C++ Standard kódtár-tároló elemeinek párhuzamos eléréséhez. A Parallel Patterns Library (PPL) biztosítja a concurrency::parallel_for_each algoritmust, amely párhuzamosan hajt végre feladatokat olyan iteratív tárolókon, mint amilyeneket a C++ Standard Library is biztosít. Ugyanazt a particionálási logikát használja, amelyet az parallel_for algoritmus használ. Az parallel_for_each algoritmus a C++ Standard Library std::for_each algoritmushoz hasonlít, azzal a kivételével, hogy az parallel_for_each algoritmus egyszerre hajtja végre a feladatokat.
// 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;
}
A kód összeállítása
Másolja ki a példakódot, és illessze be egy Visual Studio-projektbe, vagy illessze be egy elnevezett concrt-omp-count-primes.cpp fájlba, majd futtassa a következő parancsot egy Visual Studio parancssori ablakban.
cl.exe /EHsc /openmp concrt-omp-count-primes.cpp
Lásd még
Migrálás az OpenMP-ről az egyidejűségi futtatókörnyezetbe
Párhuzamos algoritmusok
párhuzamos tárolók és objektumok