C# 我是否需要检查Parallel.ForEach的小工作负载?
我的工作负载中有一组可以并行运行的项。有时候只有一个,有时候很多。当我在很大的工作负载上并行.ForEach时,速度明显加快。因此,它似乎是Parelle.ForEach的合适用法 我已经读到,对于1或2的工作负载,最好不要并行。这是否意味着我必须用这种模式包装每个工作负载大小可变的Parallel.ForEachC# 我是否需要检查Parallel.ForEach的小工作负载?,c#,task-parallel-library,parallel.foreach,C#,Task Parallel Library,Parallel.foreach,我的工作负载中有一组可以并行运行的项。有时候只有一个,有时候很多。当我在很大的工作负载上并行.ForEach时,速度明显加快。因此,它似乎是Parelle.ForEach的合适用法 我已经读到,对于1或2的工作负载,最好不要并行。这是否意味着我必须用这种模式包装每个工作负载大小可变的Parallel.ForEach if (workItems.Count==1) { foreach (MyItem item in workItems) { bool failed
if (workItems.Count==1)
{
foreach (MyItem item in workItems)
{
bool failed = WorkItWorkIt(item);
}
}
else
{
Parallel.ForEach(workItems, (item, loopState) =>
{
bool failed = WorkItWorkIt(item);
});
}
好的,
Parallel.ForEach
使用单个任务会增加一些开销,但不会太大<代码>并行。ForEach实际上将重用主线程,这意味着实际上只有一些小检查,然后它运行您的工作。两个工作项可能是有价值的,越多越好
Parallel.ForEach的更大问题实际上不是集合中的项目数量,而是每个项目完成的工作量和类型。如果您有非常小的实体(在CPU时间等方面),并行化的成本可能会很快超过好处
如果您的每项工作都受到CPU的限制并且相当大,那么总是并行化而不进行检查是相当安全的
也就是说,最好的解决方案,一如既往,是使用您所有的选项来实际分析您的应用程序。对于大多数常见任务,与维护两条代码路径的开发成本相比,有时在小工作负载下产生Parallel.ForEach()开销的CPU成本将很小,一个用于小型工作负载,另一个用于大型工作负载
除非用例中的度量结果表明相反,否则我会选择一个并行的.ForEach()实现。如果您的任务是关键的(性能方面),特别是如果您的方法worktworkit()需要某种锁定(例如,对数据表的写操作),那么这绝对是值得的,但我不会只测试一两个元素。相反,我会有一个阈值,并根据数据集大小决定最佳策略。
示例:我处理了一个真实的测试用例,其中Parallel.ForEach()需要4秒来处理数据表中的1200行,而单线程线性For只需2秒(时间的1/2)即可完成相同的任务。您可以找到相同的方法:measure。但这可能不会有多大区别。实际选择取决于任务数量和任务大小。