我正在尝试并行实现以下for循环来初始化字典。
heavy=Dict()
for item in list
heavy[item[1]]=10000000
end
其中list
是列表列表,每个项目有三个元素。
我正在尝试这样的事情:
heavy=Dict()
@parallel for item in list
heavy[item[1]]=10000000
end
然而它没有用。阅读documentation我发现了一个名为SharedArrays的东西来解决这个问题。然而,不清楚如何做同样的事情,但使用其他数据结构,如Dict()或Set()。先感谢您。
答案 0 :(得分:3)
以下方法使用缩减@parallel
来实现相同的结果:
list = [[rand(1:3),4,5] for i=1:10000000]; # define random test `list`
@everywhere rdc(d::Vector,i::Vector) = rdc(rdc(Dict(),d),i)
@everywhere rdc(d::Dict,i::Vector) = begin d[i[1]] = 1000; d end
@everywhere rdc(d::Dict,i::Dict) = merge!(d,i)
heavy = @parallel (rdc) for item in list
item
end
heavy
现在将成立:
Dict{Any,Any} with 3 entries:
2 => 1000
3 => 1000
1 => 1000
这个想法是为每个工人生成一个不同的字典,填充它并最终将字典组合成一个字典。希望结合词典的实施速度足够快,以使其值得 - 这似乎是合理的。
为了实现我们定义rdc
的想法并使用多个调度来实现它有三个目的:1)在每个worker上初始化一个新的Dict。 2)将新项目推送到工作人员的现有Dict。 3)在@parallel
的最后阶段结合来自不同工人的Dicts。上面代码中的rdc
的三种方法(按各自的顺序)实现了这一点。
避免使用SharedDict或SharedArray,因为工作人员处理不同的对象,并且最终的工作人员间通信隐藏在@parallel
实现中。
答案 1 :(得分:1)
它看起来不像共享词典。虽然Dict
基于一对Array
,一个用于键,一个用于值,但它依赖于能够在插入新项目时调整它们的大小。在工作进程中调整SharedArray
的大小似乎做了奇怪的事情,所以你不能只是将它们交换出来。
如果你可以通过增加记忆力来逃避,你可以制作一对具有正确长度的键/值SharedArray
,在并行循环中初始化它们,然后将数据复制到{{1在主要过程中。这样你就可以同时运行生成你的值的任何东西。
不幸的是,如果您的数据不是位类型,Dict
仍然会有问题。您可以使用DistributedArrays
包中的SharedArray
。