Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 28 additions & 3 deletions stdlib/Profile/src/Allocs.jl
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ A sample rate of 1.0 will record everything; 0.0 will record nothing.
julia> Profile.Allocs.@profile sample_rate=0.01 peakflops()
1.03733270279065e11

julia> results = Profile.Allocs.fetch();
julia> results = Profile.Allocs.fetch()

julia> last(sort(results.allocs, by=x->x.size))
Profile.Allocs.Alloc(Vector{Any}, Base.StackTraces.StackFrame[_new_array_ at array.c:127, ...], 5576)
Expand All @@ -52,6 +52,12 @@ macro profile(ex)
_prof_expr(ex, :(sample_rate=0.0001))
end

# globals used for tracking how many allocs we're missing
# vs the alloc counters used by @time
const _g_gc_num_before = Ref{Base.GC_Num}()
const _g_sample_rate = Ref{Real}()
const _g_expected_sampled_allocs = Ref{Float64}(0)

function _prof_expr(expr, opts)
quote
$start(; $(esc(opts)))
Expand All @@ -69,6 +75,9 @@ A sample rate of 1.0 will record everything; 0.0 will record nothing.
"""
function start(; sample_rate::Real)
ccall(:jl_start_alloc_profile, Cvoid, (Cdouble,), Float64(sample_rate))

_g_sample_rate[] = sample_rate
_g_gc_num_before[] = Base.gc_num()
end

"""
Expand All @@ -78,6 +87,15 @@ Stop recording allocations.
"""
function stop()
ccall(:jl_stop_alloc_profile, Cvoid, ())

# increment a counter of how many allocs we would expect
# the memory profiler to see, based on how many allocs
# actually happened.
gc_num_after = Base.gc_num()
gc_diff = Base.GC_Diff(gc_num_after, _g_gc_num_before[])
alloc_count = Base.gc_alloc_count(gc_diff)
expected_samples = alloc_count * _g_sample_rate[]
_g_expected_sampled_allocs[] += expected_samples
end

"""
Expand All @@ -87,6 +105,8 @@ Clear all previously profiled allocation information from memory.
"""
function clear()
ccall(:jl_free_alloc_profile, Cvoid, ())

_g_expected_sampled_allocs[] = 0
end

"""
Expand All @@ -98,8 +118,13 @@ objects which can be analyzed.
function fetch()
raw_results = ccall(:jl_fetch_alloc_profile, RawAllocResults, ())
decoded_results = decode(raw_results)
@warn("This allocation profiler currently misses some allocations. " *
"For more info see https://github.com/JuliaLang/julia/issues/43688")

missed_allocs = _g_expected_sampled_allocs[] - length(decoded_results.allocs)
missed_percentage = round(Int, missed_allocs / _g_expected_sampled_allocs[] * 100)
@warn("The allocation profiler is not fully implemented, and missed $(missed_percentage)% " *
"($(round(Int, missed_allocs)) / $(round(Int, _g_expected_sampled_allocs[]))) " *
"of allocs in the last run. " *
"For more info see https://github.com/JuliaLang/julia/issues/43688")
return decoded_results
end

Expand Down