TPL Parallel.For用于长时间运行的任务

Mat*_*ews 7 .net parallel-processing f# task-parallel-library

我想在F#中使用任务并行库(TPL)来执行许多(> 1000)长时间运行的任务.这是我目前的代码:

Parallel.For(1, numberOfSets, fun j ->
    //Long running task here
    )
Run Code Online (Sandbox Code Playgroud)

当我开始这时,似乎.NET立即启动所有任务并在它们之间不断反弹.更好的是,如果它继续执行任务,直到完成任务,然后再转移到下一个任务.这将最小化上下文切换.

有没有办法为调度程序提供提示?我知道有可能提供提示,但我找不到明确的例子,或者调度程序已经很聪明,而且只是我认为存在太多的上下文切换.谢谢您的帮助!

MiM*_*iMo 8

我们遇到了类似的问题 - 使用C#而不是F#,但库是相同的.解决方案是限制并行度:

ParallelOptions parallelOptions = new ParallelOptions();
parallelOptions.MaxDegreeOfParallelism = 16;
Parallel.For(0, n, parallelOptions, i => {
   . . . 
});
Run Code Online (Sandbox Code Playgroud)

16我们的任务运作良好 - 您应该尝试在您的情况下查看哪个值更好.

  • @Wallhood而不是硬编码值,你可以将`MaxDegreeOfParallelism`设置为`System.Environment.ProcessorCount`.您可能需要将处理器计数除以2以考虑超线程. (3认同)

pad*_*pad 5

根据我的经验,对于大量任务,最好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
Run Code Online (Sandbox Code Playgroud)

由于您正在使用F#中的并行编程,请查看优秀的"使用Microsoft .NET进行并行编程"一书,特别是关于"并行循环"的章节.@Tomas已将其样本翻译成F#,它们在这里可用.