Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
In dit voorbeeld ziet u hoe u de gelijktijdigheidsklasse gebruikt::combineerbare klasse om de som van de getallen in een std::array-object te berekenen die priem zijn. De combinable klasse verbetert de prestaties door de gedeelde status te elimineren.
Aanbeveling
In sommige gevallen kunnen parallelle toewijzing (gelijktijdigheid::parallel_transform) en reductie (gelijktijdigheid::parallel_reduce) prestatieverbeteringen bieden ten opzichte van combinable. Zie Parallelle algoritmen voor een voorbeeld waarin toewijzings- en reductiebewerkingen worden gebruikt om dezelfde resultaten te produceren als in dit voorbeeld.
Voorbeeld: verzamelen
In het volgende voorbeeld wordt de functie std::accumulate gebruikt om de som van de elementen in een matrix te berekenen die prime zijn. In dit voorbeeld a is een array object en de functie bepaalt of de is_prime invoerwaarde prime is.
prime_sum = accumulate(begin(a), end(a), 0, [&](int acc, int i) {
return acc + (is_prime(i) ? i : 0);
});
Voorbeeld: parallel_for_each
In het volgende voorbeeld ziet u een naïeve manier om het vorige voorbeeld te parallelliseren. In dit voorbeeld wordt het algoritme concurrency::parallel_for_each gebruikt om de array parallel te verwerken en een concurrency::critical_section object om de toegang tot de prime_sum variabele te synchroniseren. Dit voorbeeld wordt niet geschaald omdat elke thread moet wachten totdat de gedeelde resource beschikbaar is.
critical_section cs;
prime_sum = 0;
parallel_for_each(begin(a), end(a), [&](int i) {
cs.lock();
prime_sum += (is_prime(i) ? i : 0);
cs.unlock();
});
Voorbeeld: combineerbaar
In het volgende voorbeeld wordt een combinable object gebruikt om de prestaties van het vorige voorbeeld te verbeteren. Dit voorbeeld elimineert de noodzaak voor synchronisatieobjecten; het wordt geschaald omdat elk combinable object elke thread in staat stelt om de taak onafhankelijk uit te voeren.
Een combinable object wordt doorgaans in twee stappen gebruikt. Maak eerst een reeks fijnmazige berekeningen door parallel werk uit te voeren. Combineer vervolgens de berekeningen (of verminder ze) in een eindresultaat. In dit voorbeeld wordt de concurrency::combinable::local methode gebruikt om een verwijzing naar de lokale som te verkrijgen. Vervolgens wordt gebruikgemaakt van de concurrentie::combinable::combine-methode en een std::plus-object om de lokale berekeningen te combineren tot het uiteindelijke resultaat.
combinable<int> sum;
parallel_for_each(begin(a), end(a), [&](int i) {
sum.local() += (is_prime(i) ? i : 0);
});
prime_sum = sum.combine(plus<int>());
Voorbeeld: serieel en parallel
In het volgende volledige voorbeeld wordt de som van priemgetallen zowel serieel als parallel berekend. In het voorbeeld wordt op de console de tijd weergegeven die nodig is om beide berekeningen uit te voeren.
// parallel-sum-of-primes.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <array>
#include <numeric>
#include <iostream>
using namespace concurrency;
using namespace std;
// Calls the provided work function and returns the number of milliseconds
// that it takes to call that function.
template <class Function>
__int64 time_call(Function&& f)
{
__int64 begin = GetTickCount();
f();
return GetTickCount() - begin;
}
// 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;
}
int wmain()
{
// Create an array object that contains 200000 integers.
array<int, 200000> a;
// Initialize the array such that a[i] == i.
iota(begin(a), end(a), 0);
int prime_sum;
__int64 elapsed;
// Compute the sum of the numbers in the array that are prime.
elapsed = time_call([&] {
prime_sum = accumulate(begin(a), end(a), 0, [&](int acc, int i) {
return acc + (is_prime(i) ? i : 0);
});
});
wcout << prime_sum << endl;
wcout << L"serial time: " << elapsed << L" ms" << endl << endl;
// Now perform the same task in parallel.
elapsed = time_call([&] {
combinable<int> sum;
parallel_for_each(begin(a), end(a), [&](int i) {
sum.local() += (is_prime(i) ? i : 0);
});
prime_sum = sum.combine(plus<int>());
});
wcout << prime_sum << endl;
wcout << L"parallel time: " << elapsed << L" ms" << endl << endl;
}
De volgende voorbeelduitvoer is voor een computer met vier processors.
1709600813
serial time: 6178 ms
1709600813
parallel time: 1638 ms
De code compileren
Als u de code wilt compileren, kopieert u deze en plakt u deze in een Visual Studio-project of plakt u deze in een bestand met de naam parallel-sum-of-primes.cpp en voert u vervolgens de volgende opdracht uit in een Visual Studio-opdrachtpromptvenster.
cl.exe /EHsc-parallel-sum-of-primes.cpp
Robuuste programmering
Zie Parallelle algoritmen voor een voorbeeld waarin toewijzings- en reductiebewerkingen worden gebruikt om dezelfde resultaten te produceren.
Zie ook
parallelle containers en objecten
combineerbare klasse
critical_section-klasse