parallel_do テンプレート関数

概要

作業項目を並列に処理するテンプレート関数。

ヘッダー

 #include "tbb/parallel_do.h"

構文

template<typename InputIterator, typename Body> 
void parallel_do( InputIterator first, InputIterator last,
                 Body body[, task_group_context& group] );

template<typename Container, typename Body>
void parallel_do( Container c, Body body[, task_group_context& group] );
                

説明

parallel_do テンプレートには 2 つの形式があります。

シーケンス形式 parallel_do(first,last,body) は、シーケンス [first,last) の関数オブジェクト・ボディーに適用されます。項目は並列に処理されます。追加の作業項目は、parallel_do_feeder 型の第 2 引数がある場合、ボディーによって追加できます。body(x) が入力シーケンスまたは parallel_do_feeder::add メソッドによって追加されたすべての項目 x について返されると、関数は終了します。

コンテナー形式 parallel_do(c,body) は、parallel_do(std::begin(c),std::end(c),body) と等価です。

入力イテレーターの要件は、ISO C++ 標準のセクション 24.1 で定義されています。以下の表は、Body 型の要件を示しています。

Body B と T 型の引数に対する parallel_do の要件

擬似署名

意味

B::operator()(
cv-qualifiers T& item,
 parallel_do_feeder<T>& feeder
 ) const
または
 B::operator()(cv-qualifiers T&
item ) const
				  

item を処理します。parallel_do テンプレートは、同じ thisitem が異なる operator() を同時に呼び出します。

フィーダーの署名は、作業項目の追加を許可します。

警告

operator() の引数が 1 つの形式と引数が 2 つの形式の両方を定義することはできません。

T( const T& )

作業項目をコピーします。

~T::T()

作業項目を破棄します。

例えば、C++ 標準化仕様書のセクション 20.3 で定義されている単項関数オブジェクトは、B の要件をモデル化します。

ヒント

優れたパフォーマンスを得るには、B::operator() の粒度を ~100,000 クロックサイクル程度にします。クロックサイクルが少ない場合、parallel_do のオーバーヘッドがパフォーマンスの利点よりも上回ることがあります。

すべての項目がランダムアクセスのない入力ストリームからの項目である場合、parallel_do の並列処理はスケーラブルではありません。スケーリングを達成するには、次のいずれかを行います。

  • ランダムアクセス・イテレーターを使用して入力ストリームを指定します。parallel_for を使用することも検討してください。

  • ボディーが作業の断片を 2 つ以上追加するようなアルゴリズムを設計します。

task_group_context オブジェクトを渡して、タスクがこのグループで実行されるようなアルゴリズムにすることができます。デフォルトでは、アルゴリズムは自身がバインドされているグループで実行されます。

サンプル

次のコードは、引数が 2 つの形式の operator() のボディーを示します。

struct MyBody {
    void operator()(item_t item, 
                    parallel_do_feeder<item_t>& feeder ) {
        for each new piece of work implied by item do {
            item_t new_item = initializer;
            feeder.add(new_item);
        }
    } 
};