我正在阅读以下演示:
http://www.idt.mdh.se/kurser/DVA201/slides/parallel-4up.pdf
作者声称map函数的并行性构建得非常好(特别是他支持他在第3页或幻灯片9和10上的主张)。
如果给一个列表的每个值增加+1的问题,我可以看到强制循环列表将需要更改索引值,从而导致潜在的竞争条件问题。但我很好奇map函数如何更好地允许程序员成功地并行编码。
这是由于递归定义映射的方式吗?所以每个函数调用都可以被抛出到不同的线程?
我希望有人能提供一些细节,谢谢!
n
元素,并聚合结果。将函数应用于集合成员的顺序无关紧要,因为根据定义,函数的返回值完全取决于输入。
其他人已经解释了标准map
实现不是并行的。
但在Scala中,由于您对其进行了标记,因此您可以获得与一样简单的并行版本
val list = ... // some list
list.par.map(x => ...) // instead of list.map(x => ...)
请参阅并行集合概述和ParIterable
以及scala.collection.parallel
包中其他类型的文档。
您可以在中找到并行map
的实现https://github.com/scala/scala/blob/v2.12.1/src/library/scala/collection/parallel/ParIterableLike.scala,如果需要(查找def map
和class Map
)。它需要非常简单的基础设施,当然不仅仅是采用顺序map
的递归定义并将其并行化
如果通过循环定义映射,它会如何分解?
幻灯片在末尾和https://github.com/fsharp/fsharp/blob/master/src/fsharp/FSharp.Core/array.fs#L266你可以看到非并行的实现有一个循环:
let inline map (mapping: 'T -> 'U) (array:'T[]) =
checkNonNull "array" array
let res : 'U[] = Microsoft.FSharp.Primitives.Basics.Array.zeroCreateUnchecked array.Length
for i = 0 to res.Length-1 do
res.[i] <- mapping array.[i]
res