4

I'm observing very strange and large memory allocations while solving a standard ODE and evaluating it at given times. However, after the first benchmark, if (and only if!) I recompile the integrated function these allocations disappear.

using BenchmarkTools
import DifferentialEquations: Vern9, ODEProblem, solve

The function I'm integrating is:

@inbounds function dyn_twobody!(du::Vector{Float64}, u::Vector{Float64}, 
                                 GM::Float64, t::Float64)

    r = (u[1]*u[1] + u[2]*u[2] + u[3]*u[3])^1.5

    du[1] = u[4]
    du[2] = u[5]
    du[3] = u[6]
    du[4] = -GM*u[1]/r
    du[5] = -GM*u[2]/r
    du[6] = -GM*u[3]/r
    
    nothing 
end

while test is the function that evaluates the solution at the given times:

function test(x::Vector{Float64}, tms::Vector{Float64})

    GM_MOON = 4.902780137400001e3;
    user_prob = ODEProblem(dyn_twobody!, x, [0., 86400], GM_MOON)

    user_sol = solve(user_prob, Vern9(), abstol=1e-10, reltol=1e-9, saveat=tms, save_everystep=false).u

    return user_sol 
end

Calling it with:

x =  [50500., 232., 32321., -1.2, 0.01, 0.3];
tms = collect(LinRange(0., 86400., 86400));

@benchmark test($x, $tms)

yields:

BenchmarkTools.Trial: 30 samples with 1 evaluation.
 Range (min … max):  129.553 ms … 535.830 ms  ┊ GC (min … max): 11.32% … 74.42%
 Time  (median):     151.338 ms               ┊ GC (median):    14.82%
 Time  (mean ± σ):   167.691 ms ±  71.469 ms  ┊ GC (mean ± σ):  21.46% ± 11.46%

    ██                                                           
  ▆▇██▆▁▆▁▆▄▄▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▄ ▁
  130 ms           Histogram: frequency by time          536 ms <

 Memory estimate: 304.61 MiB, allocs estimate: 432505.

If i recompile dyn_twobody! the new benchmark is:

BenchmarkTools.Trial: 81 samples with 1 evaluation.
 Range (min … max):  49.294 ms … 106.972 ms  ┊ GC (min … max): 0.00% … 0.00%
 Time  (median):     59.441 ms               ┊ GC (median):    0.00%
 Time  (mean ± σ):   62.334 ms ±  12.016 ms  ┊ GC (mean ± σ):  2.41% ± 4.19%

  █ ▁    ▁▁    ▃                                                
  █▆█▇▄▇▇██▇▆▇▇█▁▇▆▆▆▆▄▆▆▆▄▄▁▁▄▁▁▆▆▁▁▁▄▁▁▁▁▁▁▁▆▁▁▄▁▄▄▁▁▁▁▁▁▁▁▄ ▁
  49.3 ms         Histogram: frequency by time         98.8 ms <

 Memory estimate: 17.22 MiB, allocs estimate: 173311.

Any idea what's happening with my code? I see the Garbage Collector is taking quite a lot of time

7vn_
  • 63
  • 6
  • I've seen this in the past; redefining after use drastically changing GC behavior. Still an open ticket on it: https://github.com/JuliaLang/julia/issues/35252 I would recommend switching over to static arrays for problems of this size. See: https://tutorials.sciml.ai/html/introduction/03-optimizing_diffeq_code.html – Mikael Öhman Jul 23 '22 at 21:34

0 Answers0