現在地 >> メニュー >> TBB >> TBB::基本編03::parallel_for

parallel_for


単純なループで、配列の各要素ごとに処理を与える場合、
「parallel_for」で並列化できる。

[並列化したいループの例]

const int NUM = 500;
double a[NUM];

for(int loop = 0; loop < NUM; ++loop)
{
	Function(a[loop]); //各要素にFunction()を実行する
}

並列化のためのクラスを定義


parallel_forを用いて並列化する時に必要なのは、
関数オブジェクト(クラス)であり、その中に
  • 並列処理をするデータ用のメンバ
  • コンストラクタ
  • オペレータ「()」の定義

を記述する。

※オペレータ「()」の定義部分に並列処理部分を書く。


[例]

class ADD_1000
{
private:
	double *data;  //処理用データメンバ

public:
	//コンストラクタ
	ADD_1000(double *p):data(p){}

	//オペレータ
	void operator()(const blocked_range<int>& range)const
	{
		for(int n = range.begin(); n != range.end();++n)  //並列したいループを書く
		{
			data[n] +=1000;
		}

	}
};


並列化する


並列化するには、「parallel_for」に「範囲と定義したクラス」をわたせば、
勝手に並列処理する。

[例]

class ADD_1000{ ... ... };
 ... ...

double a[NUM];
 ... ...

tbb::task_scheduler_init Tbb_Init;

 ... ...

parallel_for( blocked_range<int>(0,NUM,100),ADD_1000(a) ) //並列化

 ... ...


まず、第1引数に範囲を指定する。
 blocked_range<型>(開始位置、終了位置、grainsize(※100〜100,000ぐらい))

第2引数には、クラスをわたす。

※上の例以外にも

 ADD_1000 C_para(a);
 parallel_for( blocked_range<int>(0,NUM,100),C_para);



 ADD_1000 *C_para = new ADD_1000(a);
 parallel_for( blocked_range<int>(0,NUM,100),*C_para);

も可能。(とにかくクラスの実体をわたす)

メモ:grainsizeについて


grainsizeは分割の単位。

auto_partitioner()は一番良い分割範囲ではないが、比較的良好な結果を出すように
分割してくれる。

 parallel_for( blocked_range<int>(0,NUM),ADD_1000(a),tbb::auto_partitioner());



サンプル → TBB::parallel_for

目次

― その他 ―

Wiki内検索

計測中...(07.10.8〜)

Save The World






▲よろしければ広告のクリックもお願いします


▲ランキングに参加しました

管理人/副管理人のみ編集できます