julia @parallel for循环不更新数组

时间:2016-02-23 23:36:42

标签: for-loop multidimensional-array parallel-processing julia

我是julia的新手并且开始我想把一些numpy代码移植到julia并希望获得一些不错的性能提升。到目前为止还不令我满意。

这是我想要计算的功能

function s(x_list, r_list)
    result_list = zeros(size(x_list,1))
    for i = 1:size(x_list,1)
        dotprods = r_list * x_list[i,:]'
        expcall  = exp(im * dotprods)
        sumprod  = sum(expcall) * sum(conj(expcall))
        result_list[i] = sumprod
    end
    return result_list
end

数据输入看起来像

v = rand(3)
r = rand(6000,3)
x = linspace(1.0, 2.0, 300) * (v./sqrt(sumabs2(v)))'

对于此函数和给定的输入,@time s(x,r)给了我

0.110619 seconds (3.60 k allocations: 96.256 MB, 8.47% gc time)

对于这种情况,numpy在~70ms内做同样的工作,所以我不是很开心!现在,如果我使用@parallel for执行julia -p 2循环:

function s(x_list, r_list)
    result_list = SharedArray(Float64, size(x_list,1))
    @parallel for i = 1:size(x_list,1)
        dotprods = r_list * x_list[i,:]'
        expcall  = exp(im * dotprods)
        sumprod  = sum(expcall) * sum(conj(expcall))
        result_list[i] = sumprod
    end
    return result_list
end

问题在于

result_list[i] = sumprod

没有得到更新,我得到了从数组初始化返回的零列表。我在这做错了什么? 进一步提高速度的尝试也没有显示任何好处,例如。

@vectorize_2arg Array{Float64,2} s

并声明类型

function s{T<:Float64}(x_list::Array{T,2}, r_list::Array{T,2}) 

但是现在,在只有一个线程(没有@parallel for,只有-p2)的会话中启动相同的julia循环,数组会更新,@time s(x,r)告诉我

0.000040 seconds (36 allocations: 4.047 KB)

这实际上不可能给出功能和输入!这是一个错误吗?

非常感谢任何帮助!

2 个答案:

答案 0 :(得分:3)

Julia的@parallel宏执行分布式for循环:它将所有数据复制到其他进程并对每个进行计算,减少结果并返回结果。这些进程不共享内存 - 甚至可能完全在其他机器上。您的原始数据永远不会被触及,因为每个工作者都在修改自己的数据副本。您可能正在考虑线程,这是Julia将来会添加的当前实验性功能。

答案 1 :(得分:2)

一个问题是您没有等待@parallel来电完成。来自the docs

  

...如果不需要,可以省略减少运算符。在这种情况下,循环异步执行,即它在所有可用的worker上产生独立的任务,并立即返回Future数组而不等待完成。调用者可以稍后通过调用fetch()等待Future完成,或者在循环结束时等待完成,前缀为@sync,如@sync @parallel for。< / p>

尝试使用@sync

进行循环前缀