[kaze's test] プログラミングメモ →目次

parallel_for()関数

並列パターン ライブラリ (PPL)

parallel_for は、一定の範囲のインデックスを反復処理し、各反復処理で、ユーザーが指定した関数を並列で実行します。 
プロトタイプ:

  template <typename _Index_type, typename _Function> 
  void parallel_for(_Index_type _First, _Index_type _Last, _Index_type _Step, const _Function& _Func); 
  
  template <typename _Index_type, typename _Function > 
  void parallel_for(_Index_type _First, _Index_type _Last, const _Function& _Func);  
 
パラメーターの意味:
_Index_type:
イテレーションに使用されているインデックスの型。_Index_type は整数型である必要があります。
_Function:
各イテレーションで実行される関数の型。 
_First:
イテレーションに含まれる最初のインデックス。 
_Last:
イテレーションに含まれる最後のインデックスより 1 つ先のインデックス。 
_Step:
_First から _Last を繰り返すときのステップ値。ステップは正の数である必要があります。
ステップが 1 未満の場合は、invalid_argument がスローされます。
_Func:
各イテレーションで実行される関数。この関数は、ラムダ式、関数ポインター、
またはシグネチャ void operator()(_Index_type) を持つ関数呼び出し演算子のバージョンを
サポートするオブジェクトになります。


例:配列の足算。ラムダ式、関数ポインター、またはシグネチャ void operator()(_Index_type)の三種類の関数のそれぞれの記述方法を示します。

// parallel_for_test.cpp : コンソール アプリケーションのエントリ ポイントを定義します。
//

#include "stdafx.h"
#include <windows.h>
#include <ppl.h>
#include <iostream>

using namespace Concurrency;
using namespace std;
using namespace std::tr1;

#define DATA_NUMS 10
int a[DATA_NUMS];
int b[DATA_NUMS];
int c[DATA_NUMS];

void display_array(char* message, int* arr)
{
	cout << "### " << message << endl;
	for (int i = 0; i < DATA_NUMS; i ++)
	{
		cout << arr[i] << " ";
	}
	cout << endl << endl;
}

void add_array_serial()
{
	for (int i = 0; i < DATA_NUMS; i ++)
	{
		c[i] = a[i] + b[i];
	}
}

void add_array_parallel1()
{
	parallel_for (0, DATA_NUMS, [](int i)
	{
		c[i] = a[i] + b[i];
	}
	);
}

void add_data(int i)
{
	c[i] = a[i] + b[i];
}

void add_array_parallel2()
{
	parallel_for (0, DATA_NUMS, add_data);
}


template 
class CAddValue
{
private:
	Type Value;   // The value to add by

public:
	// Constructor initializes the value to add by
	CAddValue ( const Type& _Val ) : Value ( _Val )
	{}

	// The function call for the element to be added
	void operator ( ) ( Type index ) const
	{
		c[index] = a[index] + b[index] + Value;
	}
};

void add_array_parallel3()
{
	parallel_for (0, DATA_NUMS, CAddValue(10000));
}


int _tmain(int argc, _TCHAR* argv[])
{
	for (int i = 0; i < DATA_NUMS; i ++)
	{
		a[i] = i;
		b[i] = i * 100;
		c[i] = 0;
	}

	display_array("Array of c[]", c);

	add_array_serial();
	display_array("Array of c[]=a[]+b[] after add_array_serial()", c);

	ZeroMemory(c, sizeof(c));
	add_array_parallel1();
	display_array("Array of c[]=a[]+b[] after add_array_parallel1()", c);

	ZeroMemory(c, sizeof(c));
	add_array_parallel2();
	display_array("Array of c[]=a[]+b[] after add_array_parallel2()", c);

	ZeroMemory(c, sizeof(c));
	add_array_parallel3();
	display_array("Array of c[]=a[]+b[]+10000 after add_array_parallel3()", c);


	getchar();
	return 0;
}
出力:
### Array of c[]
0 0 0 0 0 0 0 0 0 0

### Array of c[]=a[]+b[] after add_array_serial()
0 101 202 303 404 505 606 707 808 909

### Array of c[]=a[]+b[] after add_array_parallel1()
0 101 202 303 404 505 606 707 808 909

### Array of c[]=a[]+b[] after add_array_parallel2()
0 101 202 303 404 505 606 707 808 909

### Array of c[]=a[]+b[]+10000 after add_array_parallel3()
10000 10101 10202 10303 10404 10505 10606 10707 10808 10909