Jak: zapis parallel_for_each pętli
W tym przykładzie przedstawiono sposób użycia concurrency::parallel_for_each algorytm obliczania zliczania liczb pierwszych w std::array obiektu równolegle.
Przykład
Poniższy przykład oblicza liczbę elementów w tablicy Premier dwa razy.W przykładzie najpierw użyto std::for_each algorytm obliczania seryjnie zliczania.Następnie przykładzie parallel_for_each algorytm do wykonania tego samego zadania równolegle.Przykład drukuje do konsoli również czas wymagany do wykonania obu obliczenia.
// parallel-count-primes.cpp
// compile with: /EHsc
#include <windows.h>
#include <ppl.h>
#include <iostream>
#include <algorithm>
#include <array>
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.
int n = 0;
generate(begin(a), end(a), [&] {
return n++;
});
LONG prime_count;
__int64 elapsed;
// Use the for_each algorithm to count the number of prime numbers
// in the array serially.
prime_count = 0L;
elapsed = time_call([&] {
for_each (begin(a), end(a), [&](int n ) {
if (is_prime(n))
++prime_count;
});
});
wcout << L"serial version: " << endl
<< L"found " << prime_count << L" prime numbers" << endl
<< L"took " << elapsed << L" ms" << endl << endl;
// Use the parallel_for_each algorithm to count the number of prime numbers
// in the array in parallel.
prime_count = 0L;
elapsed = time_call([&] {
parallel_for_each (begin(a), end(a), [&](int n ) {
if (is_prime(n))
InterlockedIncrement(&prime_count);
});
});
wcout << L"parallel version: " << endl
<< L"found " << prime_count << L" prime numbers" << endl
<< L"took " << elapsed << L" ms" << endl << endl;
}
Następujące przykładowe dane wyjściowe jest na komputerze z czterema procesorami.
serial version:
found 17984 prime numbers
took 6115 ms
parallel version:
found 17984 prime numbers
took 1653 ms
Kompilowanie kodu
Aby skompilować kod, skopiuj go i następnie wkleić go w projekcie programu Visual Studio lub wkleić go w pliku o nazwie równolegle z licznik primes.cpp , a następnie uruchom następujące polecenie w oknie wiersza polecenia usługi programu Visual Studio.
cl.exe /EHsc parallel-count-primes.cpp
Stabilne programowanie
Wyrażenie lambda przykładzie przekazuje do parallel_for_each używa algorytmu InterlockedIncrement funkcji, aby umożliwić równoległe iteracji pętli, aby jednocześnie przyrost wartości licznika.Jeśli używasz funkcji takich jak InterlockedIncrement do synchronizowania dostępu do zasobów udostępnionych, mogą stanowić wąskie gardła wydajności w kodzie.Można użyć mechanizmu synchronizacji zwolnić blokady, na przykład, concurrency::combinable klasy, aby wyeliminować jednoczesny dostęp do zasobów udostępnionych.Na przykład, że korzysta z combinable klasy w ten sposób, zobacz Jak: Użyj łączonymi do poprawy wydajności.