フローグラフの基本: タスクへノードをマッピング

フローグラフの基本: タスクへノードをマッピング#

以下の図は、前節で示した 2 ノードグラフの例における 1 つの実行シナリオのタイムラインを示しています。n と m の体はそれぞれ λn と λm と呼ばれます。try_put の 3 回の呼び出しにより 3 つのタスクがスポーンされ、各タスクは 3 つの入力メッセージの 1 つにラムダ式 λn を適用します。n には無制限の同時実行性があるため、スレッドが十分に利用可能であれば、これらのタスクは同時に実行できます。g.wait_for_all() の呼び出しは、グラフ内で実行中のタスクがなくなるまでブロックされます。oneTBB の他の wait_for_all 関数と同様に、wait_for_all を呼び出すスレッドは、この間スピンアイドル状態ではなく、ワークプールからの他のタスクの実行に参加できます。

2 ノードグラフの実行タイムライン

image0

n の各タスクが完了すると、m は n の後継ノードであるため、出力を m に渡します。ノード n とは異なり、m は同時実行数の上限が 1 に設定されているため、すべてのタスクをすぐにスポーンするわけではありません。代わりに、メッセージが到着した順に、そのボディー λm を実行するタスクをシーケンシャルにスポーンします。すべてのタスクが完了すると、wait_for_all の呼び出しが返されます。

フローグラフ内のすべての実行は非同期的に行われます。try_put の呼び出しは、タスクを直ちに生成するか、渡されるメッセージをバッファリングした後、呼び出し元のスレッドに制御をすぐに返します。同様に、ボディータスクはラムダ式を実行し、その結果を後続ノードに渡します。当然のことながら、wait_for_all の呼び出しのみがブロックされ、この場合でも、呼び出しスレッドは待機中に oneTBB のワークプールのタスクを実行するため使用される可能性があります。

上記のタイムラインは、並列実行できるすべてのタスクを実行するのに十分なスレッドがある場合のシーケンスを示しています。スレッド数が少ない場合、生成されたタスクの一部は、実行できるスレッドが利用可能になるまで待機します。