#include "tbb/pipeline.h"
void parallel_pipeline( size_t max_number_of_live_tokens,
const filter_t<void,void>& filter_chain
[, task_group_context& group] );
parallel_pipeline 関数は、パイプラインの構築および実行用の厳密な型のラムダ・フレンドリーなインターフェイスです。パイプラインの特性は、クラスの派生の代わりにファンクターによってパイプラインのステージが指定されることを除いて、pipeline クラスに似ています。
ファンクター g0、g1、g2、...、gn からパイプラインを構築し実行するには、次のように記述します。
parallel_pipeline( max_number_of_live_tokens,
make_filter<void,I1>(mode0,g0) &
make_filter<I1,I2>(mode1,g1) &
make_filter<I2,I3>(mode2,g2) &
...
make_filter<In,void>(moden,gn) );
一般に、ファンクター gi は、Ii 型のオブジェクトを Ii+1 型のオブジェクトにマップする operator() を定義すべきです。ファンクター g0 は、入力ストリームの最後に達するとパイプラインに通知するため、特殊なケースです。ファンクター g0 は、flow_control オブジェクト fc に対して、g0 (fc ) 式が入力ストリームの次の値を返すか、または入力ストリームの最後に達した場合は fc.stop() を呼び出し、ダミー値を返すように定義しなければなりません。
max_number_of_live_tokens 値は、pipeline::run の場合と同じ意味があります。group 引数が指定されている場合、パイプラインのタスクはこのグループで実行されます。デフォルトでは、アルゴリズムは自身がバインドされているグループで実行されます。
次のサンプルは、parallel_pipeline を使用して、[ first , last ) で定義されるシーケンスの二乗平均平方根を計算します。このサンプルは、構文の構造を示すことのみを目的としています。並列オーバーヘッドが大きすぎるため、実際の計算には適していません。& 演算子では、第 1 引数 filter_t の出力の型が第 2 引数 filter_t の入力の型と一致していなければなりません。
float RootMeanSquare( float* first, float* last ) {
float sum=0;
parallel_pipeline( /*max_number_of_live_token=*/16,
make_filter<void,float*>(
filter::serial,
[&](flow_control& fc)-> float*{
if( first<last ) {
return first++;
} else {
fc.stop();
return NULL;
}
}
) &
make_filter<float*,float>(
filter::parallel,
[](float* p){return (*p)*(*p);}
) &
make_filter<float,void>(
filter::serial,
[&](float x) {sum+=x;}
)
);
return sqrt(sum);
}
parallel_pipeline の重要な例については、インテル® TBB のチュートリアルを参照してください。