在Julia中优化剩余堆分配

krc*_*ols 6 optimization profiling allocation julia

我运行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()
Run Code Online (Sandbox Code Playgroud)

我无法摆脱线路上的最终内存分配 gradgreen....我跑了@code_warntype kernelsvals(...),没有发现任何类型的不稳定或不确定性.

分配模式在julia-0.4.6和上是相同的julia-0.5.0-pre.

这个函数将是我正在实现的边界元素方法的内核.它将被称为数百万次,导致总内存分配可以增长到我可用的物理内存的倍数.

我使用的原因FixedSizeArrays是避免与小Arrays 的创建相关的分配.

报告分配的精确位置取决于对代码的非常敏感的方式.在某些时候,内存分析器正在指责1/(4*pi*R)线路触发分配.

任何有关如何编写代码以获得可预测分配模式的帮助或一般提示都非常受欢迎.

krc*_*ols 3

经过一些实验,我终于成功摆脱了所有分配。罪魁祸首原来是 中扩展的促销架构FixedSizeArrays。显然,将复标量与实向量相乘会产生一个临时值。

\n\n

将 的定义替换gradgreen

\n\n
c = -(\xce\xb3 + 1/R) * green / R\ngradgreen = Vec(c*r[1], c*r[2], c*r[3])\n
Run Code Online (Sandbox Code Playgroud)\n\n

导致无分配运行。在我的基准测试示例中,执行时间从 6.5 秒下降到 4.15 秒。总分配大小从 4.5 GB 到 1.4 GB。

\n\n

EDT:向FixedSizeArrays开发人员报告了此问题,开发人员立即修复了该问题(谢谢!)。分配完全消失。

\n