朱莉娅有没有像SharedDict这样的东西?

时间:2016-05-02 19:42:04

标签: dictionary parallel-processing julia

我正在尝试并行实现以下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()。先感谢您。

2 个答案:

答案 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