Julia中的共享阵列用法

时间:2016-03-02 15:27:24

标签: arrays parallel-processing julia

我需要在一些工作人员之间并行完成某项任务。 为此,我需要所有工人都能访问存储数据的矩阵。

我认为数据矩阵可以实现为共享阵列,以便最大限度地减少数据移动。

为了让我开始使用共享阵列,我正在尝试以下非常简单的示例,它给出了我认为的意外行为:

julia -p 2

# the data matrix
D = SharedArray(Float64, 2, 3)

# initialise the data matrix with dummy values
for ii=1:length(D)
   D[ii] = rand()
end

# Define some kind of dummy computation involving the shared array 
f = x -> x + sum(D)

# call function on worker
@time fetch(@spawnat 2 f(1.0))

最后一个命令给出了以下错误:

 ERROR: On worker 2:
 UndefVarError: D not defined
 in anonymous at none:1
 in anonymous at multi.jl:1358
 in anonymous at multi.jl:904
 in run_work_thunk at multi.jl:645
 in run_work_thunk at multi.jl:654
 in anonymous at task.jl:58
 in remotecall_fetch at multi.jl:731
 in call_on_owner at multi.jl:777
 in fetch at multi.jl:795

我认为共享阵列D应该对所有员工都可见? 我显然遗漏了一些基本的东西。提前谢谢。

2 个答案:

答案 0 :(得分:8)

虽然基础数据是与所有员工共享的,但D的声明却没有。您仍然需要将引用传递给D,所以类似

f = (x,SA) -> x + sum(SA) @time fetch(@spawnat 2 f(1.0,D))

应该有效。您可以在主进程上更改D,并使用相同的数据查看它是非法的:

julia> # call function on worker
       @time fetch(@spawnat 2 f(1.0,D))
  0.325254 seconds (225.62 k allocations: 9.701 MB, 5.88% gc time)
4.405613684678047

julia> D[1] += 1
1.2005544517241717

julia> # call function on worker
       @time fetch(@spawnat 2 f(1.0,D))
  0.004548 seconds (637 allocations: 45.490 KB)
5.405613684678047

答案 1 :(得分:1)

这是有效的,通过函数中的闭包声明D。

function dothis()
    D = SharedArray{Float64}(2, 3)

    # initialise the data matrix with dummy values
    for ii=1:length(D)
       D[ii] = ii #not rand() anymore
    end

    # Define some kind of dummy computation involving the shared array 
    f = x -> x + sum(D)

    # call function on worker
    @time fetch(@spawnat 2 f(1.0))
end

julia> dothis()
1.507047 seconds (206.04 k allocations: 11.071 MiB, 0.72% gc time)
22.0
julia> dothis()
0.012596 seconds (363 allocations: 19.527 KiB)
22.0

因此,尽管我已经回答了OP的问题,并且SharedArray对所有工作人员都可见-这合法吗?