中の残留ヒープ割り当てを離れて最適化私は、次のような出力が得られjulia --track-allocation prof.jl
を実行しました:ジュリア
- using FixedSizeArrays
-
- immutable KernelVals{T}
- wavenumber::T
- vect::Vec{3,T}
- dist::T
- green::Complex{T}
- gradgreen::Vec{3,Complex{T}}
- end
-
- function kernelvals(k, x, y)
- r = x - y
0 R2 = r[1]*r[1]
0 R2 += r[2]*r[2]
0 R2 += r[3]*r[3]
0 R = sqrt(R2)
-
0 γ = im*k
0 expn = exp(-γ * R)
0 fctr = 1.0/(4.0*pi*R)
0 green = fctr * expn
64 gradgreen = -(γ + 1/R) * green/R * r
-
0 KernelVals(k, r, R, green, gradgreen)
- end
-
- function payload()
- x = Vec{3,Float64}(0.47046262275611883,0.8745228524771103,-0.049820876498487966)
0 y = Vec{3,Float64}(-0.08977259509004082,0.543199687600189,0.8291184043296924)
0 k = 1.0
0 kv = kernelvals(k,x,y)
- return kv
- end
-
- function driver()
- println("Flush result: ", payload())
0 Profile.clear_malloc_data()
0 payload()
- end
-
- driver()
私はgradgreen...
を開始する行の最後のメモリ割り当てを取り除くことはできません。私は@code_warntype kernelsvals(...)
を実行し、タイプの不安定性や不確実性がないことを明らかにしました。
割り当てパターンはjulia-0.4.6
とjulia-0.5.0-pre
で同じです。
この関数は、私が実装している境界要素メソッドの内部カーネルになります。文字通り何百万回も呼び出され、物理メモリの倍数になるようなメモリ割り当てが行われます。
私はFixedSizeArrays
を使用していた理由は、小さなArray
秒の作成に関連する割り当てを避けるためです。
割り当てが報告される正確な場所は、コードに非常に敏感に依存します。ある時点では、メモリプロファイラーは、ラインを割り振る割り振りとして1/(4*pi*R)
を非難していました。
予測可能な割り当てパターンをもたらすコードを書く方法に関するヘルプや一般的なヒントは高く評価されます。
これを把握し、個々のソリューションを開発し、それをグローバル化するために、うまくやってみよう! –