Visual Studio 2010 の Parallel Patterns Library (PPL) を使用Concurrency::parallel_for()
して、インデックス付きの一連のタスクを処理しています (通常、インデックス セットは、同時に実行できるスレッドの数よりもはるかに大きくなります)。各タスクは、長い計算を行う前に、共有リソース マネージャーからプライベート作業ストレージ リソースを要求することから始めます (例: タスク固有のメモリ マップ ファイルのビューですが、各タスクが共有ヒープからのプライベート メモリ割り当てを要求しました)。
共有リソース マネージャーの使用は と同期され、Concurrency::critical_section
ここから問題が始まります。最初のスレッド/タスクがクリティカル セクションにあり、2 番目のタスクが要求を行う場合、最初のタスクの要求が処理されるまで待機する必要があります。PPL はどうやら次のように考えます: このスレッドは待機中であり、実行するタスクが他にもあるため、別のスレッドが作成され、ほとんどが同じリソース マネージャーで最大 870 のスレッドを待機させます。
リソース要求の処理はタスク全体のほんの一部にすぎないので、その部分で PPL に馬を保持するように伝えたいと思います。 working-thread とここでの私の質問は、特定のスレッドセクションが協調的にブロックされていても、特定のスレッドセクションが新しいスレッドを作成するのを防ぐことができるかどうか、およびその方法です。スレッドの処理パスのさらに下にある他のブロックで新しいスレッドが作成されることは気にしませんが、(ハイパー) コアの数の 2 倍にすぎません。
これまでに検討した代替案:
タスクをキューに入れ、限られた数のスレッドからキューを処理します。問題: 私は、PPL の parallel_for が単独でそれを行うことを望んでいました。
を定義し
Concurrency::combinable<Resource> resourceSet
ます。(リソースを再利用することにより) リソース要求の数をスレッドの数 (タスクの数より少なくする必要があります) に減らすために、一度Concurrency::parallel_for
初期化します。resourceSet.local()
問題: この最適化では、余分なスレッドの作成が妨げられません。parallel_for
ループ外の各タスクに必要なリソースを事前に割り当てます。問題: これはあまりにも多くのシステム リソースを要求しますが、リソースの量をスレッド/コアの数に制限しても問題ありません (それが爆発しない場合)。
http://msdn.microsoft.com/en-us/library/ff601930.aspxのセクション「並列ループで繰り返しブロックしない」を読みましたが、ここのアドバイスに従うと、並列スレッドがまったく発生しません。