包装的并行代码比非包装

时间:2017-09-26 12:02:40

标签: parallel-processing julia

我对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由我定义DataType
  • A0是一个数组
  • 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)函数比另一个运行WAY SLOWER(如6 vs 600秒)。 这看起来非常奇怪,我不明白我做错了什么,但肯定有一些我想念的东西,所以我希望我能在这里得到一些帮助。 我正在使用Julia v0.6.0。 非常感谢您的时间和帮助。

1 个答案:

答案 0 :(得分:0)

我的猜测(无法运行有问题的代码,这真的是一个猜测)A0不是SharedArray,并且在全局定义时,它在所有处理器中都有效定义,因此不需要通信它在计算过程中(您是否注意到A0在计算中是常数?)。

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

最好拥有最大的数据位置。如果使用以下内容将A0定义为零的SharedArray:

A0 = SharedArray{Float64,3}(a_size,b_size,c_size,
                            init = S -> S[Base.localindexes(S)] .= 0)

包装和未包装的版本。此外,将每个[:,:,i]切片保留在一个处理器上是理想的(通过nworkers()除以c_size)。

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

A0 = SharedArray(otherTensor)

相关参考SharedArray documentation,其中还详述了如何在处理器之间更好地拆分SharedArray 3D张量,因此切片保留在流程中以获得更好的性能。