优化掉在朱莉娅

问题描述:

残留堆分配我跑导致下面的输出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)作为线路触发分配。

任何有关如何编写代码以获得可预测的分配模式的帮助或一般提示都将受到高度赞赏。

经过一番实验后,我终于摆脱了所有的分配。罪魁祸首竟然是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

在侦察工作上干得不错,开发一个独立的解决方案,然后将其全球化! –