20

マルチスレッドループを実行しています:

protected ParallelOptions parallelOptions = new ParallelOptions();

parallelOptions.MaxDegreeOfParallelism = 2;
Parallel.ForEach(items, parallelOptions, item =>
{
// Loop code here
});

並列ループの実行中にparallelOptions.MaxDegreeOfParallelismを変更して、スレッドの数を増減したいと思います。

parallelOptions.MaxDegreeOfParallelism = 5;

スレッドが増えていないようです。誰かアイデアはありますか?

4

2 に答える 2

6

The issue with even trying to do this is that it's a hard problem. For starters, how do you even observe CPU and disk utilization reliably? Sampling CPU infrequently will give a poor picture of what's actually going on and sampling disk utilization is even harder. Secondly, what is the granularity of your tasks and how often can you quickly can you actually change the number that are running. Thirdly things change rapidly over time so you need to apply some kind of filtering to your observations. Fourthly, the ideal number of threads will depend on the CPU that the code is actually running on. Fifthly, if you allocate too many threads you'll be thrashing between them instead of doing useful work.

使用するスレッド数を決定する複雑なタスクを .NET のスレッド プールがどのように処理するかについては、http://msdn.microsoft.com/en-us/magazine/ff960958.aspxを参照してください。

また、Reflector を使用して、TPL がスレッドを割り当て、不要なコンテキストの切り替えを回避するために使用するコードを確認することもできます。これは複雑であり、ディスク アクセスも考慮されていません。

代わりに、優先度の低いスレッドでタスクを実行してみることができます (通常よりも低い優先度でスレッドを実行する独自のスレッドを作成するのTaskSchedulerは、実際には非常に簡単です)。これにより、少なくともシステムの残りの部分に影響を与えることなく、100% の CPU を実行できることが保証されます。スレッドの優先度をいじること自体に問題が伴いますが、これが純粋にバックグラウンド タスクである場合は、簡単で役立つ可能性があります。

Often though, disk utilization is the real culprit when it comes to other applications suffering at the hands of one greedy application. Windows can allocate CPU fairly between applications with ease but when relatively slow disk access is involved it's quite another matter. Instead of trying to dynamically adjust how many thread you have running you may instead need to simply throttle your application such that it doesn't access the disk too often. That's something you can do without changing how many threads are active.

SetPriorityClassプロセスがシステム上で実行されている他のアプリケーションよりも重要でないことを OS に通知する方法として、 を参照することもできます。「プロセスのI/O 優先度を上げる方法」を参照してください。詳細については。ただし、それは、プロセスのこの部分だけでなく、プロセス全体がそれほど重要ではないことを前提としています。

于 2010-09-14T06:05:31.253 に答える
3

を呼び出した後に並列度を変更できるとは思いませんForEach。私が理解しているようにForEach、作成できるスレッドの数を決定し、その数のパーティションを作成し、それらのパーティションで動作するスレッドを作成します。「ああ、待って、彼が私たちのリソース割り当てを変更したので、配列を再パーティション化し、スレッドを再割り当てさせてください」と言えるポイントはありません。

于 2010-09-13T23:35:28.837 に答える