我在工作负载中有一组可以并行运行的项目。有时只有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);
});
}
答案 0 :(得分:7)
嗯,Parallel.ForEach
只需一个任务就会增加一些开销,但不会太大。 Parallel.ForEach
实际上会重用主线程,这意味着只有一些小支票,然后它会运行你的工作。两个工作项目可能是有价值的,更多只是更好。
Parallel.ForEach
的更大问题实际上并不是集合中的项目数量,而是每个项目的工作量和类型。如果你的身体非常小(就CPU时间等而言),并行化的成本可能会快速超过好处。
如果每个项目的工作受CPU限制并且相当大,那么在没有检查的情况下始终并行化是相当安全的。
话虽如此,一如既往,最好的解决方案是实际使用各种选项来分析您的应用程序。
答案 1 :(得分:2)
对于大多数常见任务,与维护两个代码路径的开发成本相比,有时会导致Parallel.ForEach()的小工作负载的CPU成本较小,一个用于小型工作路径,一个用于大型工作负载。
除非您的用例中的测量结果表明相反,否则我会选择单个Parallel.ForEach()实现。
答案 2 :(得分:-1)
如果您的任务很关键 - 性能方面 - 特别是如果您的方法 WorkItWorkIt() 需要某种锁定(例如对 DataTable 的写操作),那绝对值得,但我不会测试它的 1 或 2仅元素。相反,我有一个阈值,并根据数据集大小决定最佳策略。 示例:我处理了一个真实的测试用例,其中 Parallel.ForEach() 需要 4 秒来处理 DataTable 中的 1200 行,其中单线程线性 For 将在 2 秒内完成相同的任务仅(时间的 1/2)。