我正在阅读以下演示文稿:
http://www.idt.mdh.se/kurser/DVA201/slides/parallel-4up.pdf
并且作者声称地图功能非常适合并行性(特别是他在第3页或幻灯片9和10中支持他的主张)。
如果给出了将列表的每个值增加+1的问题,我可以看到如何在列表中循环,需要更改索引值,从而导致潜在的竞争条件问题。但我很好奇地图功能如何更好地允许程序员成功并行编码。
是否由于递归定义地图的方式?那么每个函数调用都可以抛出到不同的线程?
我希望有人可以提供一些细节,谢谢!
答案 0 :(得分:3)
map函数将相同的纯函数应用于集合中的async
元素并聚合结果。将函数应用于集合成员的顺序并不重要,因为根据定义,函数的返回值完全取决于输入。
答案 1 :(得分:2)
其他人已经解释过标准map
实施并不是平行的。
但是在Scala中,由于你标记了它,你可以像
一样获得并行版本val list = ... // some list
list.par.map(x => ...) // instead of list.map(x => ...)
另请参阅Parallel Collections Overview以及ParIterable
及scala.collection.parallel
包中其他类型的文档。
如果需要,您可以在https://github.com/scala/scala/blob/v2.12.1/src/library/scala/collection/parallel/ParIterableLike.scala中找到并行map
的实现(查找def map
和class Map
)。它需要非常重要的基础设施,当然不仅仅是采用顺序map
的递归定义并将其并行化。
如果通过循环定义了地图,那会怎么破坏?
幻灯片最后以F#并行数组为例,在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