TPL并行度启发式

时间:2014-10-24 11:48:24

标签: c# .net task-parallel-library

Parallel.ForEach适用于ThreadPool,默认情况下,TPL设置线程数,以便根据某些内部规则实现最高性能。但.Net是否考虑了并行或嵌套的“Parallel.Foreach”调用? 例如,假设.Net认为对于当前环境 10 线程是最佳选择,我们有:

Parallel.ForEach(collection1, (o1) => {Parallel.ForEach(collection2, (o2) => {...}})

它会产生 10 * 10 线程吗?


我发现的article让我觉得线程调度的“内部规则”是如此先进和动态,它可以合理地处理描述的案例。

1 个答案:

答案 0 :(得分:3)

它不会生成线程而是生成任务。这两个循环将indirectly cooperate。这种合作并不完美,可能导致排队的任务超过必要/最佳。每个循环使一个副本排队等待调度程序。这允许调度程序启动比最佳任务更多的任务。

在任何情况下,这并不意味着100个线程竞争OS资源。线程池用于处理超额订阅。但是,它往往会产生比CPU更多的线程,以便能够处理阻塞。

尽量避免嵌套循环。通常,最好一次只有一个并行循环。例如,你可以这样做:

var items =
 from o1 in collection1
 from o2 in collection2
 select new { o1, o2 };

Parallel.ForEach(items, ...);

如果你的架构需要嵌套循环,你可以拥有它们。