Hi there!
I am making few experiments with simple methods. This method calculates the
delay between two signals (mono-dimensional arrays) using xcorr():
function finddelay{T <: Real}(x::AbstractArray{T, 1}, u::AbstractArray{T, 1
})
# Delay as lag between cross correlation from origin of time
sₓᵤ = xcorr(x, u)
ct_idx = cld(length(sₓᵤ), 2)
_, pk_idx = findmax(sₓᵤ, 1)
δ = ct_idx - pk_idx[1]
return δ
end
Now, I would like to add a method that picks up a mono-dimensional array x,
a bi-dimensional array u, and then calculates the delay between x and each
of the columns of u. I tried this:
function finddelay{T <: Real}(x::AbstractArray{T, 1}, u::AbstractArray{T, 2
})
nᵤ = size(u, 2)
δ = Array(Int, 1, nᵤ)
for s = 1:nᵤ
δ[s] = finddelay(x, u[:, s])
end
return δ
end
It works good enough, here the benchmarks:
x = rand(10 * 192000); u = rand(10 * 192000, 3)
@benchmark finddelay(x, u)
================ Benchmark Results ========================
Time per evaluation: 1.78 s [1.65 s, 1.91 s]
Proportion of time in GC: 13.60% [10.52%, 16.69%]
Memory allocated: 878.94 mb
Number of allocations: 718 allocations
Number of samples: 4
Number of evaluations: 4
Time spent benchmarking: 9.21 s
However, by reading this cool book
<https://www.packtpub.com/application-development/julia-high-performance>,
I was suggested that using Array Views through sub() should reduce memory
usage. So I tried it:
function finddelay{T <: Real}(x::AbstractArray{T, 1}, u::AbstractArray{T, 2
})
nᵤ = size(u, 2)
δ = Array(Int, 1, nᵤ)
xs = sub(x, :, 1) # I need all arguments of xcorr() to be Views
for s = 1:nᵤ
us = sub(u, :, s)
δ[s] = finddelay(xs, us)
end
return δ
end
Which benchmarks as follows (same input arrays):
@benchmark finddelay(x, u)
================ Benchmark Results ========================
Time per evaluation: 2.44 s [2.41 s, 2.47 s]
Proportion of time in GC: 12.55% [12.54%, 12.57%]
Memory allocated: 1.07 gb
Number of allocations: 17279216 allocations
Number of samples: 3
Number of evaluations: 3
Time spent benchmarking: 9.93 s
I obtained the same benchmark by trying to copy the body of first method in
the loop of the second, adapting it to use with sub().
As such, I have few questions:
- First of all, it is good practice to nest methods like this?
- Second, why is sub associated with a huge increase in allocations? Am
I doing it wrong? Or maybe it is xcorr() that needs values and cannot work
with references?