パーティショナー

概要

パーティショナーは、スレッド間におけるループ・テンプレートのワーク分割方法を指定します。

説明

ループ・テンプレート parallel_forparallel_reduce、および parallel_scan のデフォルトの動作では、できるだけ小さくなるように分割するのではなく、プロセッサーを常に稼動状態にするのに十分なサブ範囲が確保できるように、再帰的に範囲を分割しようとします。次の表で示すように、オプションのパーティショナー引数により、ほかの動作を指定することができます。表の最初の列は、ループ・テンプレートでの仮引数の宣言方法を示しています。affinity_partitioner は、ループの反復の実行場所で更新されるため、非定数の参照で渡されます。

パーティショナー

パーティショナー

ループの動作

const auto_partitioner& (デフォルト)

Range::is_divisible で許可されている最小の粒度ではなく、負荷のバランスをとるのに十分な分割を実行します。blocked_range のようなクラスとともに使用された場合、適切な粒度の選択はあまり重要ではなくなり、通常デフォルトの粒度 1 で許容可能なパフォーマンスを達成できます。

インテル® スレッディング・ビルディング・ブロック (インテル® TBB) 2.1 では、simple_partitioner がデフォルトでした。インテル® TBB 2.2 で、ループ・テンプレートの一般的な使用を単純化するため、デフォルトが auto_partitioner に変更されました。以前のデフォルトを使用するには、プリプロセッサー・シンボル TBB_DEPRECATED=1 を指定してコンパイルしてください。

affinity_partitioner&

auto_partitioner と似ていますが、ワーカースレッドへのサブ範囲の割り当て方法により、キャッシュの有効利用を向上します。同じデータセットに対してループを再実行し、データセットがキャッシュに収まる場合、パフォーマンスが大幅に向上します。

affinity_partitionerRange で有効な場合は、比例分割を使用します。

const static_partitioner&

さらにロード・バランシングを行うことなく、ワーカースレッド間で範囲の反復をできるだけ均等に分散します。affinity_partitioner と同様に、サブ範囲をワーカースレッドにマップします。ワークの分散とマッピングには決定性があり、範囲の反復数、粒度およびスレッド数にのみ依存します。

const simple_partitioner&

範囲が分割できなくなるまで再帰的に範囲を分割します。Range::is_divisible 関数は再帰分割をいつ停止するか、決定する役割を担います。blocked_range のようなクラスとともに使用された場合、オーバーヘッドを制限する一方で並列化するために、粒度の選択は非常に重要です (「blocked_range テンプレート・クラス」セクションの説明を参照)。

関連情報