2016-07-24 113 views
7

殘留堆分配我跑導致下面的輸出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.6julia-0.5.0-pre上是相同的。

此函數將是我正在實現的邊界元素方法中的內核。這將被稱爲幾百萬次,導致一個大的內存分配,可以增長爲我可用的物理內存的一個倍數 。

我使用FixedSizeArrays的原因是爲了避免與創建小Array s有關的分配。

報告分配的確切位置取決於代碼的非常敏感的方式。在某些時候,內存分析器指責1/(4*pi*R)作爲線路觸發分配。

任何有關如何編寫代碼以獲得可預測的分配模式的幫助或一般提示都將受到高度讚賞。

回答

3

經過一番實驗後,我終於擺脫了所有的分配。罪魁禍首竟然是FixedSizeArrays的推廣架構。顯然,乘上一個複雜的標量和一個真實的矢量會創建一個臨時的路徑。

c = -(γ + 1/R) * green/R 
gradgreen = Vec(c*r[1], c*r[2], c*r[3]) 

導致自由分配,運行更換的gradgreen定義。在我的基準測試中,執行時間從6.5秒降至4.15秒。總分配大小從4.5 GB到1.4 GB。

EDT:將此問題報告給FixedSizeArrays開發人員,他們立即修復此問題(謝謝!)。分配完全消失。

+0

在偵察工作上幹得不錯,開發一個獨立的解決方案,然後將其全球化! –