[kaze's test] プログラミングメモ |
→目次 |
parallel_invoke()関数
並列パターン ライブラリ (PPL)
パラメーターとして渡された関数オブジェクトを並列実行し、実行が完了するまでブロックします。各関数オブジェクトは、ラムダ式、関数へのポインター、またはシグネチャ void operator()() を持つ関数呼び出し演算子をサポートするオブジェクトになります。
プロトタイプ:
template <
typename _Function1,
typename _Function2
>
void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2
);
template <
typename _Function1,
typename _Function2,
typename _Function3
>
void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3
);
... ... ...
... ... ...
template <
typename _Function1,
typename _Function2,
typename _Function3,
typename _Function4,
typename _Function5,
typename _Function6,
typename _Function7,
typename _Function8,
typename _Function9,
typename _Function10
>
void parallel_invoke(
const _Function1& _Func1,
const _Function2& _Func2,
const _Function3& _Func3,
const _Function4& _Func4,
const _Function5& _Func5,
const _Function6& _Func6,
const _Function7& _Func7,
const _Function8& _Func8,
const _Function9& _Func9,
const _Function10& _Func10
);
パラメーターの意味:_Function1(2,3,..,10)
並列実行される 10 番目の関数オブジェクトの型。
_Func1(2,3,..,10)
並列実行される最初の関数オブジェクト。
例:関数ポインター形式で1~10000の間の素数を数える処理、シグネチャ
void operator()()で1~900000の間の偶数を数える処理、ラムダ式で1~900000の間の奇数を数える処理
をparallel_invoke()関数で、並列実行させます。直列処理もして、所用時間を統計、表示します。
#include "stdafx.h"
#include
#include
#include
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
__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;
}
// Computes the count of prime numbers in the range [start, end).
unsigned int count_primes(int start, int end)
{
unsigned int count = 0u;
for (int n = start; n < end; ++n)
{
if (is_prime(n))
++count;
}
return count;
}
// Function object (functor) class that count the even numbers.
template
class CountEvenFunctor
{
private:
Type* pCount;
Type start;
Type end;
public:
// Constructor initialization
CountEvenFunctor ( const Type* _pVal, const Type _start, const Type _end )
{
pCount = (unsigned int *)_pVal;
start = _start;
end = _end;
}
void operator()() const
{
for (Type n = start; n < end; n ++)
{
if (n % 2 == 0)
*pCount += 1;
}
}
};
int _tmain()
{
// The count of prime numbers in various ranges.
unsigned int prime_count;
unsigned int even_count;
unsigned int odd_count;
// The total time to compute the count of prime numbers
// in all ranges.
__int64 total_elapsed;
prime_count = 0;
even_count = 0;
odd_count = 0;
wcout << L"serial version: " << endl;
total_elapsed = time_call([&]
{
__int64 elapsed;
elapsed = time_call([&] {prime_count = count_primes(0, 10000);});
wcout << L"count of prime numbers in [0, 10000): "
<< prime_count << L" (" << elapsed << L" ms)" << endl;
elapsed = time_call(CountEvenFunctor(&even_count, 0, 900000));
wcout << L"count of even numbers in [0, 900000): "
<< even_count << L" (" << elapsed << L" ms)" << endl;
elapsed = time_call([&] {
odd_count = 0;
for (int n = 0; n < 900000; n ++)
{
if (n % 2 == 1)
odd_count += 1;
}
});
wcout << L"count of odd numbers in [0, 900000): "
<< odd_count << L" (" << elapsed << L" ms)" << endl;
});
wcout << L"total time: " << total_elapsed << L" ms" << endl << endl;
// Now compute the counts in parallel for the same ranges.
prime_count = 0;
even_count = 0;
odd_count = 0;
wcout << L"parallel version: " << endl;
total_elapsed = time_call([&] {
parallel_invoke(
[&] {prime_count = count_primes(0, 10000);},
CountEvenFunctor(&even_count, 0, 900000),
[&] {
odd_count = 0;
for (int n = 0; n < 900000; n ++)
{
if (n % 2 == 1)
odd_count += 1;
}
}
);
});
wcout << L"count of prime numbers in [0, 10000): " << prime_count << endl;
wcout << L"count of even numbers in [0, 900000): " << even_count << endl;
wcout << L"count of odd numbers in [0, 900000): " << odd_count << endl;
wcout << L"total time: " << total_elapsed << L" ms" << endl << endl;
getchar();
}
出力:serial version:
count of prime numbers in [0, 10000): 1229 (31 ms)
count of even numbers in [0, 900000): 450000 (16 ms)
count of odd numbers in [0, 900000): 450000 (16 ms)
total time: 63 ms
parallel version:
count of prime numbers in [0, 10000): 1229
count of even numbers in [0, 900000): 450000
count of odd numbers in [0, 900000): 450000
total time: 31 ms
|