我理解Map如何轻松并行化 - 每台计算机/ CPU只能在阵列的一小部分上运行。
Reduce / foldl是否可并行化?似乎每个计算都取决于前一个计算。对于某些类型的函数,它是否可以并行化?
答案 0 :(得分:14)
如果您的简化基础操作是关联*,您可以使用操作和地点的顺序。因此,在“聚集”阶段,你经常会有一个树状的结构,所以你可以在对数时间内以几次传递:
a + b + c + d
\ / \ /
(a+b) (c+d)
\ /
((a+b)+(c+d))
代替(((a + b)+ c)+ d)
如果您的操作是可交换的,则可以进行进一步的优化,因为您可以按不同的顺序收集(例如,当这些操作是向量操作时,数据对齐可能很重要)
[*]你真正想要的数学运算,当然不是像浮点数那样的有效类型。
答案 1 :(得分:6)
是的,如果运营商是关联的。例如,您可以并行化对数字列表的求和:
step 1: 1 + 2 + 3 + 4 + 5 + 6 + 7 + 8
step 2: 3 + 7 + 11 + 15
step 3: 10 + 26
step 4: 36
这是因为(a + b)+ c = a +(b + c),即添加的顺序无关紧要。
答案 2 :(得分:3)
查看Hadoop中的合并阶段
答案 3 :(得分:1)
不确定您正在考虑哪种平台/语言,但您可以并行化这样的简化运算符:
// Original
result = null;
foreach(item in map) {
result += item;
}
// Parallel
resultArray = array();
mapParts = map.split(numThreads);
foreach(thread) {
result = null;
foreach(item in mapParts[thread]) {
result += item;
}
resultArray += result; // Lock this!
}
waitForThreads();
reduce(resultArray);
如您所见,并行实现很容易递归。您将地图拆分,在其自己的线程中对每个部分进行操作,然后在完成这些线程后执行另一个减少以将这些部分组合在一起。
(这是Piotr Lesnick's answer背后的程序化推理。)
答案 4 :(得分:1)
从技术上讲,缩小与foldl(fold-left)不同,后者也可以描述为累积。
Jules给出的例子非常清楚地说明了减少操作:
step 1: 1 + 2 + 3 + 4
step 2: 3 + 7
step 3: 10
请注意,在每一步中,结果都是一个数组,包括最终结果,它是一个项目的数组。
左侧折叠如下:
step 0: a = 0
step 1: a = a + 1
step 2: a = a + 2
step 3: a = a + 3
step 4: a = a + 4
step 5: a
现在显然这两者都产生相同的结果,但是当给定非关联运算符(如减法)时,foldl具有明确定义的结果,而reduce运算符则不具有。
答案 5 :(得分:0)
这取决于你的减少步骤。在MapReduce的Hadoop样式实现中,您的Reducer将被调用一次每个键,,其中所有行都与该键相关。
因此,例如,您的Mapper可能会接收大量无序的Web服务器日志,添加一些元数据(例如地理编码),并以cookie ID作为密钥发出[密钥,记录]对。然后,每个cookie ID将调用一次Reducer,并为该cookie提供所有数据,并可计算访问频率或每次访问查看的平均页面等汇总信息。或者您可以键入地理编码数据,并根据地理位置收集汇总统计数据。
即使您没有进行按键聚合分析 - 实际上,即使您在整个集合上计算某些东西 - 也许可以将计算分解成块,每个块都可以提供给Reducer