AsParallel()的最大并行度

38

在使用Parallel.ForEach时,我们可以定义并行选项并设置最大并行度,例如:

Parallel.ForEach(values, new ParallelOptions {MaxDegreeOfParallelism = number}, value = > {
    // Do Work
})

但是在使用 PLINQ 时:

Tabel.AsEnumberable()
     .AsParallel()
     .Where(//Logic)

我找不到设置 MaxDegreeOfParallelism 的方法。我在网上查找了一下,但没有找到任何信息。有人能解决这个问题吗?感谢任何帮助。

3个回答

68

你可以使用ParallelEnumerable.WithDegreeOfParallelism

设置查询中要使用的并行度。并行度是处理查询时将同时执行的任务的最大数量。

var result = Tabel.AsEnumberable()
                  .AsParallel()
                  .WithDegreeOfParallelism(number)
                  .Where(/* predicate */);

编辑:

@svick在ParallelOptions.MaxDegreeOfParallelism vs PLINQ’s WithDegreeOfParallelism一文中提供了一个很好的解释,强调了这两者之间的区别:

并行处理使用我们称之为“复制任务”的底层概念。该概念是,一个循环将从一个用于处理循环的任务开始,但如果有更多的线程可用于辅助处理,则会创建其他任务以在这些线程上运行。这使得资源消耗最小化。鉴于此,声称ParallelOptions可以指定一个DegreeOfParallelism是不准确的,因为它实际上是一个最大值:循环从1度开始,并可能随着资源变得可用而逐渐升至任何指定的最大值。

PLINQ则不同。某些重要的标准查询算子需要在执行查询的线程之间进行通信,包括一些依赖于屏障的算子,以便线程能够同步操作。PLINQ设计要求指定一定数量的线程积极参与到查询中,才能使其取得任何进展。因此,当你为PLINQ指定DegreeOfParallelism时,你是在指定实际将参与的线程数,而不仅仅是一个最大值。


4
你也许想阅读 ParallelOptions.MaxDegreeOfParallelism vs PLINQ’s WithDegreeOfParallelism,了解这两者之间的区别。 - svick
这个答案似乎与这个答案不一致。 - crokusek
@crokusek 我不确定那个回答的参考资料来自哪里,但它似乎没有通过任何官方文档来支持自己。此外,我不确定他们从哪里得到了第一个IO操作将阻塞所有其他操作的想法。听起来很奇怪。 - Yuval Itzchakov
1
不幸的是,我看到的行为与其他答案一致 - 即在4核机器上指定WithDegreeOfParallelism(32)仍然被硬限制为8。有人有证据表明,在N线程>> 2 * core的情况下直接使用该值吗? - crokusek
从我所做的一个小测试来看,实际线程数似乎并不等于DegreeOfParallelism。我将DegreeOfParallelism分配为100,并运行了一个小程序,记录每个“任务”的线程ID - 实际上只使用了9个线程。我是在.Net 4.5.1中运行的。 - omer schleifer
显示剩余4条评论

9

是的,您可以这样做。您只需使用WithDegreeOfParallelism扩展方法即可。

yourSequence.AsParallel()
    .WithDegreeOfParallelism(5)//Whatever number as you like
    .Where(...);

0
<IEnumerable>.AsParallel()
.WithDegreeOfParallelism(n)
.Where(x=>)

1
@codingpirate 只是好奇,您为什么在一个几乎一年后的回答中选择了一个与我的回答完全相同的答案,并将我的回答取消了接受标记?有什么特别的原因吗? - Yuval Itzchakov
@YuvalItzchakov - 为了关闭这个线程,我接受了答案。话虽如此,我也接受了你的解释作为答案。 - codingpirate

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接