I’m trying to implement a zero-allocating version of a normal distribution pdf
, but get some unexpected allocations. Below is my code for a script ./test_allocations.jl
, which could be ran to test allocations quickly.
using StaticArrays
using Profile
module T
using StaticArrays
using LinearAlgebra
CovMat = SMatrix{3, 3, Float64}
MeanVec = SVector{3, Float64}
struct MvNormalF
μ::MeanVec;
Σ::CovMat;
pdf_divider::Float64;
Σ_inv::CovMat;
MvNormalF(μ::MeanVec, Σ::CovMat) = new(μ, Σ, 0.5 * log((2π)^3 * det(Σ)), inv(Σ))
end
@inbounds function vXvt(a::Float64, b::Float64, c::Float64, m::CovMat)
return a*a*m[1, 1] + b*b*m[2, 2] + c*c*m[3, 3] + 2*a*b*m[1, 2] + 2*a*c*m[1, 3] + 2*b*c*m[2, 3]
end
@inbounds log_pdf(d::MvNormalF, x::SVector{3, Float64})::Float64 =
vXvt(x[1] - d.μ[1], x[2] - d.μ[2], x[3] - d.μ[3], d.Σ_inv)
function test_pdf_perf(comp::MvNormalF, x::SVector{3, Float64}; n::Int)
for i in 1:n
log_pdf(comp, x)
end
end
end
x = SVector{3}(0., 1., 1.);
comp = T.MvNormalF(T.MeanVec(0., 0., 0.), T.CovMat(1., 0., 0., 0., 1., 0., 0., 0., 1.))
T.test_pdf_perf(comp, x; n=10);
Profile.clear_malloc_data()
T.test_pdf_perf(comp, x; n=10);
If I run it with julia --track-allocation=all ./test_allocations.jl
, it shows that the only allocation is 640 bytes for the line @inbounds log_pdf(...)
. What is the reason of these allocations or how can I find its source?