【问题标题】:Do I need to check Parallel.ForEach for small workloads?对于小型工作负载,我是否需要检查 Parallel.ForEach?
【发布时间】:2014-06-03 10:48:30
【问题描述】:

我有一组可以并行运行的工作负载项目。有时只有 1 个,有时有很多。当我在大量工作负载上使用 Parallel.ForEach 时,它明显更快。所以这似乎是 Parelle.ForEach 的合适用法。

我已经阅读过,对于 1 或 2 的工作负载,最好不要使用 Parallel.ForEach。这是否意味着我必须用这种模式包装可变工作负载大小的每个 Parallel.ForEach?

if (workItems.Count==1)
{
    foreach (MyItem item in workItems)
    {
        bool failed = WorkItWorkIt(item);
    }
}
else
{
    Parallel.ForEach(workItems, (item, loopState) =>
        {
            bool failed = WorkItWorkIt(item);
        });
}

【问题讨论】:

  • 你可以用同样的方法找到:测量。但它可能不会有太大的不同。实际选择取决于任务的数量和任务的大小。

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


【解决方案1】:

嗯,Parallel.ForEach 使用单个任务会增加一些开销,但不会很大。 Parallel.ForEach 实际上会重用主线程,这意味着实际上只有一些小的检查,然后它会运行你的工作。两个工作项可能是值得的,而且越多越好。

Parallel.ForEach 的更大问题实际上并不是集合中的项目数量,而是每个项目正在完成的工作的数量和类型。如果您的主体非常小(在 CPU 时间等方面),并行化的成本很快就会超过收益。

如果您的每个项目的工作受 CPU 限制且相当大,那么始终并行化是相当安全的,无需检查。

话虽如此,最好的解决方案一如既往地是使用所有各种选项实际分析您的应用程序。

【讨论】:

    【解决方案2】:

    对于大多数常见任务,与维护两条代码路径(一条用于小型工作负载,一条用于大型工作负载)的开发成本相比,有时为小型工作负载产生 Parallel.ForEach() 开销的 CPU 成本会很小。

    除非您的用例中的测量结果表明相反,否则我会选择单个 Parallel.ForEach() 实现。

    【讨论】:

      【解决方案3】:

      如果你的任务很关键——性能方面——特别是如果你的方法 WorkItWorkIt() 需要某种锁定(例如对 DataTable 的写入操作),那绝对值得,但我不会测试它 1 或 2仅元素。相反,我有一个阈值,并根据数据集大小决定什么是最佳策略。 示例:我处理了一个真实的测试案例,其中 Parallel.ForEach() 需要 4 秒来处理 DataTable 中的 1200 行,其中单线程线性 For 将在 2 秒内完成相同的任务仅(1/2 时间)。

      【讨论】:

        猜你喜欢
        • 2015-12-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-02-21
        • 2019-09-25
        相关资源
        最近更新 更多