2016-05-01 16 views
1

と私は、このコード(プリミティブ熱伝達を)持っている:私は1つ上で実行しても遅く順次実行したときにジュリア著しく遅い@parallel

function heat(first, second, m) 
    @sync @parallel for d = 2:m - 1 
     for c = 2:m - 1 
      @inbounds second[c,d] = (first[c,d] + first[c+1, d] + first[c-1, d] + first[c, d+1] + first[c, d-1])/5.0; 
     end 
    end 
end 

m = parse(Int,ARGS[1]) #size of matrix 
firstm = SharedArray(Float64, (m,m)) 
secondm = SharedArray(Float64, (m,m)) 

for c = 1:m 
    for d = 1:m 
     if c == m || d == 1 
      firstm[c,d] = 100.0 
      secondm[c,d] = 100.0 
     else 
      firstm[c,d] = 0.0 
      secondm[c,d] = 0.0 
     end 
    end 
end 
@time for i = 0:opak 
    heat(firstm, secondm, m) 
    firstm, secondm = secondm, firstm 
end 

このコードは、良い時間を与えるが、私はそれ@parallel追加するとき糸。なぜこれが起こっているのか説明が必要なだけですか?熱機能のアルゴリズムを変更しない場合にのみコーディングしてください。

+0

は私が共有配列の異なる要素を読んでパラレル更新が/実際に動作することを確認していませんよ。 –

+0

は 'SharedArray'における各参加プロセスのみのアレイのローカルインデックスに動作するかどうか、それはOK動作するはず@RezaAfzalan。 OPは、並列計算ドキュメントから[移流例](http://docs.julialang.org/en/latest/manual/parallel-computing/#id2)を見ていますか?私はそれが非常に有用であることが分かった'localindices'で区切られた境界に注意してください。 –

+0

並列コンピューティングとは関係ありませんが、早期に作成すると便利です。Juliaでは、 'firstm'と' secondm'を行ではなく列で埋め込む方が効率的です。外側ループに 'd'インデックスを入れ、内側ループに' c'変数を入れてみてください。 –

答えて

8

http://docs.julialang.org/en/release-0.4/manual/performance-tips/を見てください。アドバイスとは逆に、グローバル変数を多く使用します。彼らはいつでも型を変更するとみなされるので、参照されるたびにボックス化され、ボックス化されていなければなりません。この質問にもJulia pi aproximation slowは同じです。関数を高速化するには、関数の入力引数としてグローバル変数を使用します。

+0

それは私のπ近似の問題を解決しましたが、関数パラメータにはすべての変数があります。私が言ったように、これはスムーズに実行されますが、@parallelなしでのみ実行されます。そして残念ですが、熱に反復を追加するのを忘れました(これらの行列を切り替える必要があります)。編集済み – pavelf

+0

'@ sync'は不要だと思います。ループは以前のループに依存しないので、それを省略します。 –

+0

@syncを消去した後、正しい答えが返されません。また、警告が表示されました。警告:すべての労働者を終了することができません:強制的に WARNING忙しい労働者を中断 – pavelf

2

考慮すべきいくつかのポイントがあります。それらの1つはmのサイズです。

julia 36967257.jl 4000 
# Parallel: 
0.054848 seconds (4.46 k allocations: 241.935 KB) 
# Normal: 
3.779843 seconds (29.13 k allocations: 1.308 MB) 

プラス2備考:

1 /初期化の大きなmあなたが持っている可能性があり、より良い結果を得るために

julia 36967257.jl 4 
# Parallel: 
0.040434 seconds (4.44 k allocations: 241.606 KB) 
# Normal: 
0.042141 seconds (29.13 k allocations: 1.308 MB) 

:それが小さい場合には、並列処理がないため、大きなゲインを多くのオーバーヘッドを与えるだろう次のように簡略化することができます。

for c = 1:m, d = 1:m 
    if c == m || d == 1 
     firstm[c,d] = 100.0 
     secondm[c,d] = 100.0 
    else 
     firstm[c,d] = 0.0 
     secondm[c,d] = 0.0 
    end 
end 

2/your finite differences schema安定していない。 Linear multistep methodまたはADI/Crank Nicolsonをご覧ください。