2012-11-24 8 views
7

F#でTPL(Task Parallel Library)を使用して、長時間(> 1000)の長時間実行されるタスクを実行したいと考えています。ここに私の現在のコードは次のとおりです。私はこれを起動するとTPL並列実行時間が長いタスク

Parallel.For(1, numberOfSets, fun j -> 
    //Long running task here 
    ) 

.NETが一度にすべてのタスクを開始し、常にそれらの間でバウンドことが表示されます。それは次のものに移動する前に完了するまで、それがタスクにとどまっていればよいでしょう。これにより、コンテキストの切り替えが最小限に抑えられます。

スケジューラにヒントを提供する方法はありますか?私はヒントを提供することは可能ですが、明確な例が見つからないか、スケジューラがこれについて賢明であることを知っています。コンテキストスイッチが多すぎるというのは私の認識です。助けてくれてありがとう!

答えて

8

F#ではなくC#を使用して同様の問題が発生しましたが、ライブラリは同じです。解決策は、並列度を制限することでした:

ParallelOptions parallelOptions = new ParallelOptions(); 
parallelOptions.MaxDegreeOfParallelism = 16; 
Parallel.For(0, n, parallelOptions, i => { 
    . . . 
}); 

16を私たちの仕事のためによく働いた - あなたはあなたのケースで優れている値を参照するために実験する必要があります。

+0

私よりも速く+1秒です。 –

+0

MaxDegreeOfParallelismはマシンのコア数に依存しますか? –

+0

@Wallhood:タスクがCPUバウンドの場合はおそらくyes、タスクがIOバウンド(ファイル処理、DBへのアクセス)の場合はおそらくそうではありません。私たちの場合、通常の状況では値が2/4コアで正常に機能したため、より洗練されたものを試す本当の理由はありませんでした。たとえば、16コアのスーパーマシンで実行される可能性の高いプログラムではありません。 – MiMo

5

私の経験から言えば、多くのタスクでは、Environment.ProcessorCountに直線的にMaxDegreeOfParallelismをバインドする方が良いでしょう。ここで

ミモの1つのF#構文では@に類似したコード断片である:

let options = ParallelOptions() 
options.MaxDegreeOfParallelism <- Environment.ProcessorCount * 2 

Parallel.For(0, n, options, 
      (fun i -> (* Long running task here *))) |> ignore 

あなたはF#での並列プログラミングで作業しているので、優れた書籍"Parallel Programming with Microsoft .NET"、特に章をご覧ください"Parallel Loops"にあります。 @トーマスはそのサンプルをF#に翻訳しました。利用可能なのはhereです。

1

リファレンスソースを見ると、次のコードは、労働者の数を決定する表示されます、既定のタスクスケジューラとデフォルトParallelOptionsでこれがEnvironment.ProcessorCountに評価され、私の知る限り

// initialize ranges with passed in loop arguments and expected number of workers 
int numExpectedWorkers = (parallelOptions.EffectiveMaxConcurrencyLevel == -1) ? 
    Environment.ProcessorCount : 
    parallelOptions.EffectiveMaxConcurrencyLevel; 

をだからあなた自身がプロセッサ数にMaxDegreeOfParallelismを指定して別の動作をしているのは変です。私はあなたが実際に違いがあることを確認するためにデバッグすることをお勧めします(Thread.ManagedThreadIdを長時間実行するタスクの中に印刷することができます)。

+0

大きな違いがありました。最大同時実行性を指​​定すると、コアごとに一度に1つのタスクしか開きません。私がそれを指定しなかった場合、すべてのタスクが一度に開かれます。それは一度に一つずつしか働いていないかもしれませんが、それらはすべて開いていました。私は各タスクのタイマーを開始するという事実からこれを推測しています。並列性を指定したとき、各タスクの時間は同じでした。私がしなかったとき、仕事は完了するのに非常に長い時間がかかることがありました。何が起きているのか分かりませんが、それは私の観察です。 –

+0

労働者数と「MaxDegreeOfParallelism」は2つの異なるものでしょうか?私は@Wallhoodが何を言っているかを確認しています.1000のタスクが並行して起動していて、それらがマシンを停止していたときに、「MaxDegreeOfParallelism」を設定しなくても問題は16に設定されていました(CPUではなく、 – MiMo

関連する問題