Julia @parallel for loop 不更新数组



我是 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 内完成相同的工作,所以我不是很开心!现在,如果我用julia -p 2做一个@parallel for循环:

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}) 

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

0.000040 seconds (36 allocations: 4.047 KB)

对于给定的功能和输入来说,这实际上是不可能的!这是一个错误吗?

任何帮助都非常感谢!

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

一个问题是您没有等待@parallel调用完成。从文档中:

。如果不需要归约运算符,可以省略它。在这种情况下,循环异步执行,即它在所有可用的工作线程上生成独立的任务,并立即返回 Future 数组,而无需等待完成。调用方可以通过调用 fetch() 来等待稍后的 Future 完成,或者通过在循环末尾加上@sync前缀来等待完成,例如 @sync @parallel for

尝试在循环的前缀加上@sync