【问题标题】:TPL parallelism degree heuristicTPL并行度启发式
【发布时间】:2014-10-24 21:36:19
【问题描述】:

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

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

它会产生 10*10 个线程吗?


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

【问题讨论】:

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


    【解决方案1】:

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

    无论如何,这并不意味着有 100 个线程在争夺操作系统资源。线程池用于处理超额订阅。但是,它往往会产生比 CPU 更多的线程,以便能够处理阻塞。

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

    var items =
     from o1 in collection1
     from o2 in collection2
     select new { o1, o2 };
    
    Parallel.ForEach(items, ...);
    

    如果您的架构需要嵌套循环,您可以使用它们。

    【讨论】:

    • 并非所有情况都允许这样的合并。为什么你认为 100 是任务数量而不是线程?恕我直言线程池是这里的关键点,任务数可以更多。还有about nested loops
    • 不是线程,因为并行循环不处理线程。他们不开始任何。那个链接很有趣。它使我的部分答案无效。但不是结论:虽然不是最优的,但有这些循环是可以的。线程池启动的“副本”可能比最佳状态更多。
    • 他们不是 1:1。池将任务排队并将它们分派到较少数量的线程上。线程数由启发式选择。
    • 好吧,我没完全看懂这篇文章。也许任务和线程池有两种启发式。
    • 循环中的任务并没有真正的启发式。循环将新任务排队,直到调度程序饱和。调度程序通常是一个线程池调度程序。线程池具有线程数的启发式。
    猜你喜欢
    • 1970-01-01
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-25
    相关资源
    最近更新 更多