Scala 2.9并行集合背后的工作原理是什么?

28

Scala 2.9引入了并行集合,它们对某些任务来说是非常好的工具。然而,它们的内部工作原理是什么,我能够影响其行为/配置吗?

它们使用什么方法来确定最佳线程数?如果我不满意结果,是否有任何配置参数可以调整?

我不仅对实际创建的线程数量感兴趣,还对实际工作在这些线程之间如何分配感兴趣。结果如何收集以及幕后发生了多少魔术。Scala是否会测试集合是否足够大以从并行处理中受益?

1个回答

29
简而言之,您的操作并行化有两个正交方面:
1.将集合分成块的程度(即块的大小)用于可并行化操作(例如map或filter) 2.用于执行并行任务的基础fork-join池中使用的线程数
对于第2点,池本身管理此操作,它在运行时发现“理想”的并行级别(请参见java.lang.Runtime.getRuntime.availableProcessors)
对于第1点,这是一个单独的问题,scala并行集合API通过工作窃取(自适应调度)的概念来解决这个问题。也就是说,当完成特定的工作时,工作者将尝试从其他工作队列中窃取工作。如果没有可用的工作,则表明所有处理器都非常繁忙,因此应该采取更大的工作量。
Aleksandar Prokopec实现了该库,并在今年的ScalaDays上发表了一篇演讲,该演讲不久将在线上发布。他还在ScalaDays2010上发表了一篇很棒的演讲,其中详细描述了如何拆分和重新连接操作(有一些不明显的问题和一些聪明的技巧!)。 PDF描述并行集合API提供了更全面的答案。

谢谢你的回答!我不知道那篇关于实现细节的论文。我会把它放在我的阅读清单上,以备接下来的几天。如果我理解正确,平行集合是为了始终并行实现的。因此,如果我创建的集合在大小上有很大差异,我必须自己判断何时使用并行列表而不是顺序列表才能得到好处,或者我理解错了吗? - Steffen
1
我非常确定这是正确的。最近曾讨论过编译器中List用法的可并行性,并采取了测量措施,显示大多数List大小在1-5元素之间。这意味着在代码中将List替换为ParSeq就没有任何意义。 - oxbow_lakes
1
嗯,在这种情况下,拥有一个 parIfLargerThan(N:Int) 函数将是很棒的。它只会在集合大小大于 N(在运行时)时并行化。 - HRJ
@oxbow_lakes 这取决于一个线程处理1个元素需要多长时间。如果需要很长时间,您可能会在大小为2的ParSeq上获得2倍的加速。 - arya

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