2017-09-26 61 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'如果是常量?謝謝您的幫助! –