我是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)
这实际上不可能给出功能和输入!这是一个错误吗?
非常感谢任何帮助!
答案 0 :(得分:3)
Julia的@parallel
宏执行分布式for循环:它将所有数据复制到其他进程并对每个进行计算,减少结果并返回结果。这些进程不共享内存 - 甚至可能完全在其他机器上。您的原始数据永远不会被触及,因为每个工作者都在修改自己的数据副本。您可能正在考虑线程,这是Julia将来会添加的当前实验性功能。
答案 1 :(得分:2)
一个问题是您没有等待@parallel
来电完成。来自the docs:
...如果不需要,可以省略减少运算符。在这种情况下,循环异步执行,即它在所有可用的worker上产生独立的任务,并立即返回Future数组而不等待完成。调用者可以稍后通过调用
fetch()
等待Future完成,或者在循环结束时等待完成,前缀为@sync
,如@sync @parallel for
。< / p>
尝试使用@sync