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 章で定義されています。以下の表は、Body 型の要件を示しています。

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

擬似署名

意味

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

item を処理します。parallel_do は、同じボディー・オブジェクトで item が異なる operator() を同時に呼び出します。

フィーダーの署名は、ワークアイテムの追加を許可します。

注意

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

T( const T& )

ワークアイテムをコピーします。

~T::T()

ワークアイテムを破棄します。

ヒント

優れたパフォーマンスを得るには、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);
        }
    } 
};