@lmiq
I doubt that it can be parallelized, since it’s internal Base
function. Yet on the other hand, I also doubt that it would be useful, since this function is mostly doing memory operations and memory operations rarely profit from parallelization (memory is much slower than CPU). As an example compare these two implementations (they are not very efficient, but it is not important, since we use the same operations in both versions)
using BenchmarkTools
x = [rand(10000) for _ in 1:100]
y = Vector{Float64}(undef, 1000000)
function f1!(y, x)
for i in axes(x, 1)
for j in axes(x[i], 1)
y[(i - 1)*length(x[1]) + j] = x[i][j]
end
end
return y
end
function f2!(y, x)
Threads.@threads for i in axes(x, 1)
for j in axes(x[i], 1)
y[(i - 1)*length(x[1]) + j] = x[i][j]
end
end
return y
end
and result is
julia> Threads.nthreads()
8
julia> @btime f1!($y, $x);
@btime f2!($y, $x);
1.305 ms (0 allocations: 0 bytes)
julia> @btime f2!($y, $x);
1.201 ms (41 allocations: 5.89 KiB)
The speedup that you observe was mainly related to the parallelization of the generation of the tables, which uses rand
and it is a rather costly operation.
@Juan
From hvcat
documentation:
Horizontal and vertical concatenation in one call. This function is called for block matrix
syntax. The first argument specifies the number of arguments to concatenate in each block
row.
If the first argument is a single integer n, then all block rows are assumed to have n block
columns.
So, the first argument to hvcat
in our example is (2)
and it means, that we only want two columns. Consider for example
julia> hvcat((2), 1, 2, 3, 4, 5, 6)
3×2 Array{Int64,2}:
1 2
3 4
5 6
julia> hvcat((3), 1, 2, 3, 4, 5, 6)
2×3 Array{Int64,2}:
1 2 3
4 5 6
Now, hvcat
do not accept vectors of matrices as an input, so I should have written
hvcat(2, rand(5, 5), rand(5, 5), rand(5, 5), rand(5, 5))
which is of course not scalable and inconvenient if we have a large number of matrices. But hvcat
is so called Vararg function and I’ve used splatting syntax, when you add ellipsis to the last argument and julia split it into proper number of positional arguments. For easier understanding it can be written in two lines
rand_matrices = [rand(5, 5) for _ in 1:4]
hvcat(2, rand_matrices...) # which during parsing turns internally to hvcat(2, rand_matrices[1], rand_matrices[2], rand_matrices[3], rand_matrices[4])
So as a conclusion, I generated vector of 4 matrices 5x5 and said to hvcat
to reorganize them in two block columns.
@HenriDeh
All kudos should go to @rafael.guerra