2017-09-26 59 views
0

我对Julia相对较新,在尝试平行化时遇到一些问题。 我已经尝试了pmap@parallel两种方法,并遇到同样的问题。 当我运行类似:包装并行代码的方式比非包装更慢

addprocs(7) 
A0=zeros(a_size, b_size, c_size) 
A=SharedArray{Float64}(a_size,b_size,c_size) 
toler=1e-3 
maxit=1000 
while (metric1>toler) && (iter1<maxit) 
`@inbounds` `@sync` `@parallel` for i in 1:c_size 
A[:,:,i]=compute_A(fs,A0[:,:,i],i) 
end 
A_new=sdata(A) 
metric1=maximum(abs.((A_new-A0))) 
A0=copy(A_new) 
iter1=iter1+1 
println("$(iter1) $(metric1)") 
end 

其中函数compute_A的输入为:

  • fs是通过我
  • A0定义DataType是一个数组
  • i被索引I循环(尺寸c_size)

这似乎是工作的罚款(即使不是共享的阵列和@parallel环路我使用pmap)

然而,当我使用的是收官之作功能的代码,如:

wrap(fs::DataType, toler::Float64, maxit::Int) 
A0=zeros(a_size, b_size, c_size) 
A=SharedArray{Float64}(a_size,b_size,c_size) 

    while (metric1>toler) && (iter1<maxit) 
`@inbounds` `@sync` `@parallel` for i in 1:c_size 
    A[:,:,i]=compute_A(fs,A0[:,:,i],i) 
end 
A_new=sdata(A) 
metric1=maximum(abs.((A_new-A0))) 
A0=copy(A_new) 
iter1=iter1+1 
println("$(iter1) $(metric1)") 
end 
end 

呼叫此wrap(fs, 1e-3, 1000)函数运行的方式比另一个更慢(如6 vs 600秒)。 这似乎非常奇怪,我不明白我做错了什么,但肯定有一些我错过了,所以我希望我可以在这里得到一些帮助。 我正在使用Julia v0.6.0。 非常感谢您的时间和帮助。

回答

0

我的猜测(没有能力运行代码,这实在是个猜测)是A0不是SharedArray,并且在全局定义时,它在所有处理器中都有效定义,因此在计算过程中不需要进行通信(你注意到A0在你的计算中是一个常量?)。

在包装版本中,它在本地定义在一个进程中并不断与其他进程进行通信。因此运行时间较长。

最好是有最大的数据位置。

A0 = SharedArray{Float64,3}(a_size,b_size,c_size, 
          init = S -> S[Base.localindexes(S)] .= 0) 
两个包裹的未包装的版本

:如果您在使用定义A0为零的SharedArray。此外,保持每个[:,:,i]切片在一个处理器上将是理想的(通过nworkers()划分c_size)。

注意:我不确定在将代码放在问题中之前进行了何种编辑,但如果A0确实是一个恒定的零张量,那么可能有更好的方法来重构代码。如果A0一些其他的张量,然后尝试:

A0 = SharedArray(otherTensor) 

一个相关的参考SharedArray documentation其中还详细介绍了如何更好地分割处理器之间的SharedArray三维张量,所以片仍然是一个进程内为更好的性能。

+0

谢谢@DanGetz!但只是一个澄清,因为我仍然有点困惑与并行计算。所以基本上所有在并行计算的函数中的输入都必须定义为共享数组,如果数组和'@everywhere'如果是常量?谢谢您的帮助! –