方法: parallel_for_each ループを記述する
次の使用例を使用する方法を示しています、 concurrency::parallel_for_each 内の素数の数を計算するアルゴリズムは、 std::array 並行オブジェクト。
使用例
次の例では、配列に含まれる素数の数を 2 回計算します。最初に、std::for_each アルゴリズムを使用して、逐次的に数を計算します。次に、parallel_for_each アルゴリズムを使用して、同じタスクを並列に実行します。また、それぞれの計算に要する時間もコンソールに出力します。
// 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;
}
4 つのプロセッサを備えたコンピューターを使用したときのサンプル出力を次に示します。
serial version:
found 17984 prime numbers
took 6115 ms
parallel version:
found 17984 prime numbers
took 1653 ms
コードのコンパイル
コードをコンパイルするには、コピーし、Visual Studio プロジェクト内に貼り付けるまたはという名前のファイルに貼り付けて並列・ カウント ・ primes.cpp と、Visual Studio のコマンド プロンプト ウィンドウで次のコマンドを実行します。
cl.exe /EHsc parallel-count-primes.cpp
信頼性の高いプログラミング
この例で parallel_for_each アルゴリズムに渡すラムダ式では、InterlockedIncrement 関数を使用して、ループの反復処理を並列で行い、カウンターを同時にインクリメントします。InterlockedIncrement などの関数を使用して共有リソースへのアクセスを同期化すると、コードのパフォーマンスのボトルネックを示すことができます。たとえば、ロックを解放する同期メカニズムを使用できますが、 concurrency::combinable クラスは、共有リソースへの同時アクセスを回避するのには。combinable クラスのこのような使用例については、「方法: combinable を使用してパフォーマンスを向上させる」を参照してください。