首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >矩阵或三维数组的julia向量

矩阵或三维数组的julia向量
EN

Stack Overflow用户
提问于 2021-10-09 14:53:59
回答 1查看 97关注 0票数 1

我想把几个矩阵(所有相同的维数)相乘,得到一个向量beta。我尝试了两个版本,来存储矩阵,或者作为矩阵的向量,或者作为三维数组。

带有矩阵向量的版本运行得更快是正常的吗?

代码语言:javascript
运行
复制
using BenchmarkTools

nid =10000
npar = 5
x1 = reshape(repeat([1], nid * npar), nid,:)
x2 = reshape(repeat([2], nid * npar), nid,:)
x3 = reshape(repeat([3], nid * npar), nid,:)
X = reshape([x1 x2 x3], nid, npar, :);
X1 = [x1, x2, x3]
beta = rand(npar)



  function f(X::Array{Int,3}, beta::Vector{Float64})::Array{Float64}
     hcat([ X[:,:,i] * beta  for i=1:size(X,3)]...)
   end

   function g(X::Array{Array{Int,2},1}, beta::Vector{Float64})::Array{Float64}
  hcat([X[i] * beta for  i=1:size(X)[1]]...)
end

f(X,beta);
g(X1,beta);

@benchmark f(X, beta)
@benchmark g(X1, beta)

结果表明,f几乎是g的2倍。这是一个正常的模式,还是我没有正确使用3D Array?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-10-09 15:28:46

这是因为切片运算符会强制复制每个矩阵,从而导致内存分配增长。

请注意基准测试的最后一行:

代码语言:javascript
运行
复制
julia> @benchmark f(X, beta)
BenchmarkTools.Trial: 8011 samples with 1 evaluation.
 Range (min … max):  356.013 μs …   4.076 ms  ┊ GC (min … max): 0.00% … 87.21%
 Time  (median):     457.231 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   615.235 μs ± 351.236 μs  ┊ GC (mean ± σ):  6.54% ± 11.69%

  ▃▇██▆▅▄▄▄▃▂        ▂▃▄▄▄▃▁▁▁ ▁   ▁                            ▂
  ████████████▆▇▅▅▄▄▇███████████████▇█▇▇█▇▆▇█▆▆▆▆▅▆▅▅▄▃▃▂▂▄▂▄▄▄ █
  356 μs        Histogram: log(frequency) by time       1.96 ms <

 Memory estimate: 1.60 MiB, allocs estimate: 17.

julia> @benchmark g(X1, beta)
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (min … max):  174.348 μs …   2.493 ms  ┊ GC (min … max): 0.00% … 83.85%
 Time  (median):     219.383 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   245.192 μs ± 119.612 μs  ┊ GC (mean ± σ):  3.54% ±  7.68%

   ▃▇█▂                                                          
  ▅████▆▄▄▃▃▃▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▁▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂▂ ▃
  174 μs           Histogram: frequency by time          974 μs <

 Memory estimate: 469.25 KiB, allocs estimate: 11.

要避免这种情况,只需使用强制引用的宏@views,而不进行分配。然后,两个实现之间的时间在随机噪声中变得相同:

代码语言:javascript
运行
复制
function fbis(X::Array{Int,3}, beta::Vector{Float64})::Array{Float64}
   @views  hcat([ X[:,:,i] * beta  for i=1:size(X,3)]...)
end


julia> @benchmark fbis(X, beta)
BenchmarkTools.Trial: 10000 samples with 1 evaluation.
 Range (min … max):  175.984 μs …   2.710 ms  ┊ GC (min … max): 0.00% … 79.70%
 Time  (median):     225.990 μs               ┊ GC (median):    0.00%
 Time  (mean ± σ):   274.611 μs ± 166.015 μs  ┊ GC (mean ± σ):  4.17% ±  7.78%

   ▅█▃                                                           
  ▆███▆▄▃▄▄▃▂▂▂▂▂▂▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁▁ ▂
  176 μs           Histogram: frequency by time         1.15 ms <

 Memory estimate: 469.25 KiB, allocs estimate: 11.

虽然在这种情况下使用引用可以提高基准测试,但请注意不要滥用它们。如果您正在“创建”一些您将反复使用的矩阵,那么如果您复制矩阵,则初始分配时间与使用引用方式的不同内存空间的查找时间相比可能会变得微不足道。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/69507845

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档