簡體   English   中英

TPL Parallel.For用於長時間運行的任務

[英]TPL Parallel.For with long running tasks

我想在F#中使用任務並行庫(TPL)來執行許多(> 1000)長時間運行的任務。 這是我目前的代碼:

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

當我開始這時,似乎.NET立即啟動所有任務並在它們之間不斷反彈。 更好的是,如果它繼續執行任務,直到完成任務,然后再轉移到下一個任務。 這將最小化上下文切換。

有沒有辦法為調度程序提供提示? 我知道有可能提供提示,但我找不到明確的例子,或者調度程序已經很聰明,而且只是我認為存在太多的上下文切換。 謝謝您的幫助!

我們遇到了類似的問題 - 使用C#而不是F#,但庫是相同的。 解決方案是限制並行度:

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

16我們的任務運作良好 - 您應該嘗試在您的情況下查看哪個值更好。

根據我的經驗,對於大量任務,最好將MaxDegreeOfParallelism線性綁定到Environment.ProcessorCount

這是一個與FMI語法中的@Mimo相似的代碼片段:

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

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

由於您正在使用F#中的並行編程,請查看優秀的“使用Microsoft .NET進行並行編程”一書,特別是關於“並行循環”的章節。 @Tomas已將其樣本翻譯成F#,它們在這里可用。

查看參考源,看來下面的代碼確定了工作者的數量:

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

據我所知,使用默認的任務調度程序和默認的ParallelOptions,它的計算結果為Environment.ProcessorCount ,所以通過自己指定MaxDegreeOfParallelism到處理器數量來獲得不同的行為是很奇怪的。 我建議你調試以確保確實存在差異(你可以在長時間運行的任務中打印Thread.ManagedThreadId )。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM