Lin*_*don 8 in-place blas lapack julia
我很好奇为什么Julias实现矩阵添加似乎可以复制.下面是一个例子:
foo1=rand(1000,1000)
foo2=rand(1000,1000)
foo3=rand(1000,1000)
julia> @time foo1=foo2+foo3;
0.001719 seconds (9 allocations: 7.630 MB)
julia> sizeof(foo1)/10^6
8.0
Run Code Online (Sandbox Code Playgroud)
分配的内存量与这些维度矩阵所需的内存大致相同.
看起来为了处理foo2 + foo3,内存被分配来存储结果,然后foo1通过引用分配给它.
这是否意味着对于大多数线性代数运算,我们需要直接调用BLAS和LAPACK函数来执行操作?
spe*_*on2 13
要了解这里发生了什么,让我们考虑foo1 = foo2 + foo3实际做了什么.
foo2 + foo3.为此,它将分配一个新的临时数组来保存输出foo1到这个新的临时数组,撤消您为预分配输出数组而付出的所有努力.简而言之,您会看到内存使用情况与结果数组的内存使用情况有关,因为例程确实为该大小的数组分配了新内存.
以下是一些替代方案:
broadcast!copy!(foo1, foo2+foo3),然后你预先分配的数组将被填充,但它仍将分配临时(见下文)这是这4个案例的一些代码
julia> function with_loop!(foo1, foo2, foo3)
for i in eachindex(foo2)
foo1[i] = foo2[i] + foo3[i]
end
end
julia> function with_broadcast!(foo1, foo2, foo3)
broadcast!(+, foo1, foo2, foo3)
end
julia> function with_copy!(foo1, foo2, foo3)
copy!(foo1, foo2+foo3)
end
julia> function original(foo1, foo2, foo3)
foo1 = foo2 + foo3
end
Run Code Online (Sandbox Code Playgroud)
现在让我们来看看这些功能吧
julia> for f in [:with_broadcast!, :with_loop!, :with_copy!, :original]
@eval $f(foo1, foo2, foo3) # compile
println("timing $f")
@eval @time $f(foo1, foo2, foo3)
end
timing with_broadcast!
0.001787 seconds (5 allocations: 192 bytes)
timing with_loop!
0.001783 seconds (4 allocations: 160 bytes)
timing with_copy!
0.003604 seconds (9 allocations: 7.630 MB)
timing original
0.002702 seconds (9 allocations: 7.630 MB, 97.91% gc time)
Run Code Online (Sandbox Code Playgroud)
你可以看到with_loop!并broadcast!做同样的事情,两者都比其他人更快,更有效率.with_copy!并且original速度较慢并且使用更多内存.
一般来说,要做就地操作,我建议先写一个循环
| 归档时间: |
|
| 查看次数: |
547 次 |
| 最近记录: |