Shuhua
March 29, 2021, 7:13am
1
Julia Version 1.5.3
julia> f(a, b, c) = a + b - c;
julia> X = randn(1000, 5);
julia> y = zeros(1000);
# feed the last three columns of `X` into `f` and write the result into `y`
julia> @btime $y .= f((view($X, :, j) for j = 3:5)...);
1.922 μs (9 allocations: 16.23 KiB)
julia> @btime $y .= @views f(($X[:, j] for j = 3:5)...);
1.922 μs (9 allocations: 16.23 KiB)
I have three questions:
What causes the large memory allocation in both cases?
Why is there a significant time difference between view
and @views
? ([updated] Due to the error mentioned by @sijo )
What is the recommended way to achieve the above goal, i.e., broadcasting over multiple columns of a matrix?
sijo
March 29, 2021, 7:45am
2
You forgot to interpolate X
in the first case
1 Like
First thing to note, you’re interpolating the value of X
in the second but not the first case.
julia> @btime $y .= f((view($X, :, j) for j = 3:5)...);
1.234 μs (2 allocations: 15.88 KiB)
julia> @btime $y .= @views f(($X[:, j] for j = 3:5)...);
1.127 μs (2 allocations: 15.88 KiB)
You might leave away the interpolation altogether and do
julia> @btime y .= f((view(X, :, j) for j = 3:5)...) setup=(X = randn(1000, 5); y = rand(1000););
1.347 μs (2 allocations: 15.88 KiB)
julia> @btime y .= @views(f((X[:,j] for j = 3:5)...)) setup=(X = randn(1000, 5); y = rand(1000););
1.186 μs (2 allocations: 15.88 KiB)
(This is on Julia 1.6.)
1 Like
sijo
March 29, 2021, 7:51am
4
Note that you need 1.6 to get only 2 allocations… On 1.5.3 I get 11.
Shuhua
March 29, 2021, 7:51am
5
Thanks. But I cannot understand where the 2 allocations: 15.88 KiB
comes.
See @sijo ’s comment. I’m running Julia 1.6.
sijo
March 29, 2021, 7:59am
7
It depends on the specific requirements but this doesn’t allocate at all (either on 1.5 or 1.6):
julia> @btime y .= (@views X[:,3] .+ X[:,4] .- X[:,5]) setup=(X = randn(1000, 5); y = rand(1000));
182.881 ns (0 allocations: 0 bytes)
Elrod
March 29, 2021, 8:00am
8
You weren’t broadcasting f
, so it was allocating a result that you then used a broadcast to copy into y
.
3 Likes
Implementing @Elrod ’s comment:
Julia 1.6:
julia> @btime y .= f.((view(X, :, j) for j = 3:5)...) setup=(X = randn(1000, 5); y = rand(1000););
133.359 ns (0 allocations: 0 bytes)
julia> @btime y .= @views(f.((X[:,j] for j = 3:5)...)) setup=(X = randn(1000, 5); y = rand(1000););
139.092 ns (0 allocations: 0 bytes)
Julia 1.5:
julia> @btime y .= f.((view(X, :, j) for j = 3:5)...) setup=(X = randn(1000, 5); y = rand(1000););
711.807 ns (9 allocations: 624 bytes)
julia> @btime y .= @views(f.((X[:,j] for j = 3:5)...)) setup=(X = randn(1000, 5); y = rand(1000););
729.203 ns (9 allocations: 624 bytes)
2 Likes
Shuhua
March 29, 2021, 8:07am
10
Thanks. A stupid mistake.