3

驚異的並列化可能なタスクを多数実行する必要がある問題に取り組んでいます。タスクはデータベースからデータを読み取ることによって作成されますが、すべてのタスクのコレクションはマシン上のメモリの量を超えるため、タスクを作成、処理、および破棄する必要があります。この問題を解決するための良いアプローチは何でしょうか?私は次の2つのアプローチを考えています。

  1. 同期されたタスクキューを実装します。データベースからデータを読み取り、タスクをキューに入れるプロデューサー(タスククリエーター)を実装します(メモリの量を超えないように、現在キューにあるタスクの数を一定の値に制限します)。キューからタスクを読み取り、タスクを処理し、結果を保存してタスクを破棄する複数のコンシューマープロセス(タスクプロセッサ)を用意します。このアプローチでは、消費者プロセスの数はどれくらいになるでしょうか。

  2. .NET Parallel拡張機能(PLINQまたはparallel for)を使用しますが、タスクのコレクションを作成する必要があることを理解しています(Parallel forで処理しているときに、コレクションにタスクを追加できますか?)。したがって、タスクのバッチを作成します。たとえば、一度にN個のタスクを作成し、これらのタスクのバッチを処理して、別のN個のタスクを読み取ります。

これら2つのアプローチについてどう思いますか?

4

6 に答える 6

4

システムを圧倒しないように、制限されたキューでThreadPoolを使用してください。

各ワーカータスクがCPUにバインドされている場合は、システム内のスレッドの数がボックスで実行できるハードウェアスレッドの数と等しくなるように、最初にシステムを構成します。

タスクがCPUにバインドされていない場合は、プールサイズを試して、特定の状況に最適なソリューションを取得する必要があります。

最適な構成を実現するには、いずれかのアプローチを試す必要がある場合があります。

基本的に、テスト、調整、テスト、満足するまで繰り返します。

于 2009-05-07T15:09:32.387 に答える
3

PLINQを実際に使用する機会はありませんでしたが、PLINQ(バニラLINQなど)がIEnumerableに基づいていることは知っています。そのため、これは、C#イテレータブロック(つまり、yieldキーワード)を介してタスクプロデューサーを実装することが理にかなっている場合だと思います。

タスクのセット全体を事前に知っておく必要のある操作(注文など)を行っていない場合、PLINQは一度に処理できる数のタスクしか消費しないと思います。また、この記事では、PLINQが入力を消費する方法を制御するためのいくつかの戦略について説明します(「クエリ出力の処理」というタイトルのセクション)。

編集:PLINQをThreadPoolと比較します。

このMSDNの記事によると、スレッドプールに作業を効率的に割り当てることは決して簡単なことではなく、「正しく」行ったとしても、TPLを使用すると一般的にパフォーマンスが向上します。

于 2009-05-07T15:19:02.707 に答える
2

ThreadPoolを使用します。

次に、すべてをキューに入れることができ、システムを圧倒することなくスレッドがプールで使用可能になると、アイテムが実行されます。唯一の秘訣は、一度に実行するスレッドの最適な数を決定することです。

于 2009-05-07T15:03:01.467 に答える
1

Microsoft HPC Server 2008の仕事のように聞こえます。圧倒的なタスクの数を考えると、ある種の並列プロセスマネージャーが必要です。それがHPCサーバーのすべてです。

http://www.microsoft.com/hpc/en/us/default.aspx

于 2009-05-07T15:02:05.213 に答える
0

良い答えを出すために、いくつかの質問に答える必要があります。

個々のタスクは並列化可能ですか?または、各タスクは並列化可能なメインタスクの結果ですか?

また、システムのメモリ不足を引き起こすタスクの数ですか、それとも各タスクが保持するデータとシステムのメモリ不足を引き起こすプロセスの量ですか?

于 2009-05-07T15:55:38.703 に答える
-1

これを行うには、 Windows Workflow Foundation(WF)を使用するのが良いかもしれません。また、タスクの一時停止/再開など、いくつかの追加の利点が得られる場合もあります。

于 2009-05-07T19:15:41.563 に答える