パーティショナーは、スレッド間におけるループ・テンプレートのワーク分割方法を指定します。
ループ・テンプレート parallel_for、parallel_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_partitioner が Range で有効な場合は、比例分割を使用します。 |
const static_partitioner& |
さらにロード・バランシングを行うことなく、ワーカースレッド間で範囲の反復をできるだけ均等に分散します。affinity_partitioner と同様に、サブ範囲をワーカースレッドにマップします。ワークの分散とマッピングには決定性があり、範囲の反復数、粒度およびスレッド数にのみ依存します。 |
const simple_partitioner& |
範囲が分割できなくなるまで再帰的に範囲を分割します。Range::is_divisible 関数は再帰分割をいつ停止するか、決定する役割を担います。blocked_range のようなクラスとともに使用された場合、オーバーヘッドを制限する一方で並列化するために、粒度の選択は非常に重要です (「blocked_range テンプレート・クラス」セクションの説明を参照)。 |