从矩阵向量中减去矩阵的最佳方法
Best way to subtract Matrix from Vector of Matrix
我想从矩阵向量中减去一个矩阵。例如,在下面定义的变量中,我想为 xl
的每个元素减去 y
xl = [Matrix{Float64}(undef, 2, 3) for i in 1:1000]
y = Matrix{Float64}(undef, 2, 3)
我知道这可以用地图函数来完成
map(x -> x-y, xl)
但是有没有更好的方法来做到这一点,或者我们可以通过多线程来减少运行时间吗?我尝试对简单地图和 ThreadsX.map 进行基准测试,发现 ThreadsX.map 比任何减少运行时间的建议都慢。
@btime map(x -> x-y, xl); # 55.558 μs (1010 allocations: 117.59 KiB)
@btime ThreadsX.map(x -> x-y, xl); # 99.764 μs (5414 allocations: 285.47 KiB)
注意:这里的 Matrix 只是一个示例,我想在支持减法的自定义结构的大向量上执行此操作。
默认情况下,Julia 仅从一个线程开始。要使用多个线程启动 Julia,您可以使用 --threads=n
选项:
PS C:\Users\Elias> julia --threads=4
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.7.2 (2022-02-06)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> xl = [rand(2, 3) for i in 1:1000];
julia> y = rand(2, 3);
julia> using ThreadsX
julia> using BenchmarkTools
julia> @btime ThreadsX.map(x -> x-$y, $xl);
42.700 μs (1353 allocations: 206.77 KiB)
详情请见:https://docs.julialang.org/en/v1/manual/multi-threading/
首先,map
并不是最快的,循环几乎总是能打败它。这个数组理解比 map
.
快 70%
@btime [[x[i]-$y[i] for i in eachindex($y)] for x in $xl];
33.300 μs (1001 allocations: 117.31 KiB)
现在,对于多线程速度较慢的原因,答案可能是此简单计算的多线程设置具有 non-negligible 开销。您希望对多线程进行更繁重的计算以产生显着效果。另外,不要忘记在 @btime
.
计时时插入 ($
)
@btime map(x -> x-$y, $xl);
55.600 μs (1001 allocations: 117.31 KiB)
@btime $xl .- ($y,); # broadcasting
56.100 μs (1001 allocations: 117.31 KiB)
@btime ThreadsX.map(x -> x-$y, $xl);
53.600 μs (1602 allocations: 242.05 KiB)
看这个更重的例子,多线程加速大约 6 倍:
julia> @btime ThreadsX.map(x -> exp.(sin.(x))-exp.(sin.($y)), $xl);
303.700 μs (3605 allocations: 460.89 KiB)
julia> @btime map(x -> exp.(sin.(x))-exp.(sin.($y)), $xl);
1.673 ms (3001 allocations: 336.06 KiB)
我想从矩阵向量中减去一个矩阵。例如,在下面定义的变量中,我想为 xl
的每个元素减去 yxl = [Matrix{Float64}(undef, 2, 3) for i in 1:1000]
y = Matrix{Float64}(undef, 2, 3)
我知道这可以用地图函数来完成
map(x -> x-y, xl)
但是有没有更好的方法来做到这一点,或者我们可以通过多线程来减少运行时间吗?我尝试对简单地图和 ThreadsX.map 进行基准测试,发现 ThreadsX.map 比任何减少运行时间的建议都慢。
@btime map(x -> x-y, xl); # 55.558 μs (1010 allocations: 117.59 KiB)
@btime ThreadsX.map(x -> x-y, xl); # 99.764 μs (5414 allocations: 285.47 KiB)
注意:这里的 Matrix 只是一个示例,我想在支持减法的自定义结构的大向量上执行此操作。
默认情况下,Julia 仅从一个线程开始。要使用多个线程启动 Julia,您可以使用 --threads=n
选项:
PS C:\Users\Elias> julia --threads=4
_
_ _ _(_)_ | Documentation: https://docs.julialang.org
(_) | (_) (_) |
_ _ _| |_ __ _ | Type "?" for help, "]?" for Pkg help.
| | | | | | |/ _` | |
| | |_| | | | (_| | | Version 1.7.2 (2022-02-06)
_/ |\__'_|_|_|\__'_| | Official https://julialang.org/ release
|__/ |
julia> xl = [rand(2, 3) for i in 1:1000];
julia> y = rand(2, 3);
julia> using ThreadsX
julia> using BenchmarkTools
julia> @btime ThreadsX.map(x -> x-$y, $xl);
42.700 μs (1353 allocations: 206.77 KiB)
详情请见:https://docs.julialang.org/en/v1/manual/multi-threading/
首先,map
并不是最快的,循环几乎总是能打败它。这个数组理解比 map
.
@btime [[x[i]-$y[i] for i in eachindex($y)] for x in $xl];
33.300 μs (1001 allocations: 117.31 KiB)
现在,对于多线程速度较慢的原因,答案可能是此简单计算的多线程设置具有 non-negligible 开销。您希望对多线程进行更繁重的计算以产生显着效果。另外,不要忘记在 @btime
.
$
)
@btime map(x -> x-$y, $xl);
55.600 μs (1001 allocations: 117.31 KiB)
@btime $xl .- ($y,); # broadcasting
56.100 μs (1001 allocations: 117.31 KiB)
@btime ThreadsX.map(x -> x-$y, $xl);
53.600 μs (1602 allocations: 242.05 KiB)
看这个更重的例子,多线程加速大约 6 倍:
julia> @btime ThreadsX.map(x -> exp.(sin.(x))-exp.(sin.($y)), $xl);
303.700 μs (3605 allocations: 460.89 KiB)
julia> @btime map(x -> exp.(sin.(x))-exp.(sin.($y)), $xl);
1.673 ms (3001 allocations: 336.06 KiB)