I’m trying to understand where it’s happening and how much of the time it’s taking. The gc time seems relatively small, but I assume memory allocation takes time too.
The hierarchical Profile.print() has a left-most column labelled Overhead. What is this supposed to represent? Memory allocation time? JIT time? sampler time?
Profiling · The Julia Language does not discuss the Overhead column, and the sample outputs there don’t even include it.
That same page does say
specific lines triggering allocation can often be inferred from profiling via the cost of garbage collection that these lines incur.
How exactly can one tell the cost of garbage collection? Is it the overhead field? Will it appear as an explicit call in the profile stack?
More substantively, I thought the places and time gc was triggered were somewhat random, and not necessarily the place the memory was allocated.
And, to repeat, what if I want to measure allocation directly? Do I need to go to the --track-allocation option, which apparently requires a restart of Julia?
You would only see allocations there. GC only happens as pat of those (possibly). If you have many threads I believe you could have no allocations, except in some other thread you’re not tracking and it would slow down doing GC.
I can’t help you with the overhead column (I never use Profile.print), but I would recommend trying to view profiles with ProfileView.jl. In my opinion, it’s much easier to look at than Profile.print.
When viewing the profile, look for orange and red bars. The orange ones show where allocations happen and the red ones show where dynamic dispatch happens. Dynamic dispatch can also be a source of allocations and can sometimes be very bad for performance.
Since your function only takes about two seconds to complete, maybe try running it a few times to get a better view of the profile.
@profiler (I’m using Juno) has same colors as ProfileView.jl. Doesn’t directly show allocations but if the allocations result in slow code, profiling should help focus the search.
@code_warntype to find memory allocations related to type-instability.
for --track-allocation I write a script like
function g(n, T)
sum([rand(T) for _ in 1:n])
end
@time g(1, Float64)
using Profile
Profile.clear_malloc_data()
@time g(100, Float64)
exit()
file = @__FILE__
run(`julia --track-allocation=user $file`)
The last lines are because I’m using Juno and too lazy to open a terminal.
Sprinkle @time inside the suspicious function to see if the allocations also result in time spent. This only works in one level at a time because @time @time results in many allocations. Somehow this is the most precise method I know to measure memory allocations.