Hello,
Iβm facing a memory allocation problem on an apparently simple case. I have the following struct
struct MyStruct{T1<:AbstractMatrix, T2}
data::T1
other::T2
end
where data
is a matrix and other
is something that will not be involved in the next operations, but we will see it will lead to memory allocations.
Now I show how I get memory allocations when performing operations on a Tuple
of these objects, with different types for the other
field.
using LinearAlgebra
using BenchmarkTools
struct MyStruct{T1<:AbstractMatrix, T2}
data::T1
other::T2
end
struct MyStructSum{T}
ops::T
end
function LinearAlgebra.mul!(y::AbstractVector, a::MyStruct, x::AbstractVector)
mul!(y, a.data, x)
return y
end
function LinearAlgebra.mul!(y::AbstractVector, a::MyStructSum, x::AbstractVector)
for op in a.ops
mul!(y, op, x)
end
return y
end
T = Float64
N = 200
M = 10
ops = ntuple(i-> rand(T, N, N), Val(M))
vals = ntuple(i-> rand() > 0.5 ? rand(Int64) : rand(Float64), Val(M))
my_structs = ntuple(i-> MyStruct(ops[i], vals[i]), Val(M))
my_sum_struct = MyStructSum(my_structs)
typeof(my_sum_struct)
x = rand(T, N)
y = similar(x)
mul!(y, my_sum_struct, x);
@benchmark mul!($y, $my_sum_struct, $x)
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
Range (min β¦ max): 37.297 ΞΌs β¦ 135.552 ΞΌs β GC (min β¦ max): 0.00% β¦ 0.00%
Time (median): 37.902 ΞΌs β GC (median): 0.00%
Time (mean Β± Ο): 38.379 ΞΌs Β± 2.357 ΞΌs β GC (mean Β± Ο): 0.00% Β± 0.00%
ββββββββ ββββββ β
βββββββββββββββββββββββββββββββ
βββββββββββ
ββ
β
β
ββββββββββββββ β
37.3 ΞΌs Histogram: log(frequency) by time 46.1 ΞΌs <
Memory estimate: 1.86 KiB, allocs estimate: 19.
How course, if all the other
fields have the same time, then I donβt have memory allocations. But in my complete implementation I need them, and in general they will be function types.
How can I solve this problem, knowing that the mul!
operation is performed only in the data
field, and it doesnβt use there other
at all?