私は並列処理の概念全体をよりよく理解しようとしており、テストケースを設定しました。テストを試してみたところ、Dataflow ActionBlock
(またはTransformBlock
)内でAsyncメソッド呼び出しを使用してもパフォーマンスにプラスの影響はなく、コードが複雑になるだけであることがわかりました。Dataflowブロックを使用している場合、その中のコードは非同期である必要はなく、Dataflowがそれ自体で非同期にするというのは正しいと思います。それとも私はポイントを逃していますか?
2 に答える
TPL Dataflow は同時実行または並列化を有効にしません (ただし、ActionBlock
その処理を並列化することはできます)。これは、並列コードまたは並列コードがデータを通信するために使用するものです。とりわけ、これはメッセージ パッシングのメカニズムであり、共有データに代わるものです。共有データを複数のスレッドで使用する場合、高価な同期が必要になります。処理が必要なデータはメッセージにカプセル化され、処理対象のコードに「送信」されるため、メッセージの受け渡しが正しく行われれば、同期は必要ありません。
TPL データフローは、特定の設計がある場合に使用できるものです。アクター ベースのプログラミング、メッセージ パッシング、ノンブロッキング プロデューサー/コンシューマー シナリオなどを具体的に実装していない場合、TPL データフローによって複雑になる可能性があります。
このようなシステムを設計したいと考えている場合は、Stephen Toub (Microsoft の並列チームのメンバー) によるビデオやDataflow MSDN ページなど、TPL Dataflow (TDF) を理解するための優れたリソースがいくつかあります。
アップデート:
ブロックの最大並列度を設定できますが、それを CPU やコアの数より高く設定すると、多くの場合逆効果になります。実行される各アクションは、多かれ少なかれ CPU バウンド (実行中に CPU を 100% 使用) であると想定されています。アクションが待機に多くの時間を費やす場合 (待機ハンドルの待機、メッセージ ポンプでのメッセージの待機 (アクションでは正常ではなく、UI スレッドの場合) など) は、並列度を超えるCPU の数は理にかなっているかもしれません (ただし、微調整するのは難しいでしょう)。実行中の CPU よりも多くのアクションを実行している場合CPUバウンドでは、実際にOSにタスクを課し始めます。OS は、「実行中」であるため、各スレッド (またはこの場合は各アクション) に CPU 時間を割り当てたいと考えています。周回するのに十分な CPU がない場合、OS はアクティブな各スレッドに CPU 時間を与えるラウンドロビン方式のマルチタスクをプリエンプティブに開始します。OS が 1 つのスレッドから CPU を奪い、それを別のスレッドに渡すたびに、コンテキスト スイッチングと呼ばれます。これは非常に高価です (2000-8000 cpu サイクルの範囲)。そのため、OS は実際にはコンテキストの切り替えにすべての時間を費やしており、アクションを実行していません。
アクションが実際に非同期である場合、ブロックの並列度は関係ありません。他の何かが並列化を行っているからです。ただし、同じ問題が発生し、非同期アクションがチェックされずに実行され、導入するコンテキスト切り替えの程度で OS を圧倒するリスクがあります。この制御の欠如のために、非同期アクションを実行しないことを真剣に検討します。
TPL Dataflow は、すべての種類の並列処理に適しているわけではなく、コードを魔法のように高速化することもできません。
TDF の背後にある主なアイデアは、独立して作業を行うブロックがあるということです。これが意味することは、各ブロックの作業を個別のスレッドで実行できるため、TDF を使用したコードの並列化が非常に簡単になる場合があるということです。
これは、ブロック内のコードが共有できないリソースを使用している場合に特に役立ちます。このようにして、このブロックの処理は他のブロックから独立しているため、その共有リソースを最大限に活用できます。
一般に、TDF は、コードがパイプラインのようなものである場合に最適です。アイテムが入ってきて、フェーズ 1 で処理され、次にフェーズ 2 で処理され、…、そして最後に出力されます。ただし、データフロー ネットワークはそれよりもはるかに複雑になる可能性があります。ただし、これを強制しようとするべきではありません。やりたいことが TDF にうまく適合しない場合は、コードを複雑にするだけで何のメリットもありません。