gpt4 book ai didi

julia - 在 Julia 中索引数组时避免内存分配

转载 作者:行者123 更新时间:2023-12-03 23:20:52 25 4
gpt4 key购买 nike

更新:注意Julia v1+中的相关函数是view 问题:我想在不触发内存分配的情况下对数组进行索引,尤其是在将索引元素传递给函数时。通过阅读 Julia 文档,我怀疑答案围绕着使用 sub 展开。功能,但不太明白如何...
工作示例:我构建了一个 Float64 的大向量( x ) 然后是 x 中每个观察值的索引.

N = 10000000
x = randn(N)
inds = [1:N]
现在我计时 mean函数结束 xx[inds] (我首先运行 mean(randn(2)) 以避免任何编译器在时间上的违规行为):
@time mean(x)
@time mean(x[inds])
这是一个相同的计算,但正如预期的那样,计时结果是:
elapsed time: 0.007029772 seconds (96 bytes allocated)
elapsed time: 0.067880112 seconds (80000208 bytes allocated, 35.38% gc time)
那么,对于 inds 的任意选择,是否有办法解决内存分配问题? (以及任意选择数组和函数)?

最佳答案

只需使用 xs = sub(x, 1:N) .请注意,这与 x = sub(x, [1:N]) 不同;在 julia 0.3 上,后者将失败,而在 julia 0.4-pre 上,后者将比前者慢得多。在 Julia 0.4-pre 上,sub(x, 1:N)view 一样快:

julia> N = 10000000;

julia> x = randn(N);

julia> xs = sub(x, 1:N);

julia> using ArrayViews

julia> xv = view(x, 1:N);

julia> mean(x)
-0.0002491126429772525

julia> mean(xs)
-0.0002491126429772525

julia> mean(xv)
-0.0002491126429772525

julia> @time mean(x);
elapsed time: 0.015345806 seconds (27 kB allocated)

julia> @time mean(xs);
elapsed time: 0.013815785 seconds (96 bytes allocated)

julia> @time mean(xv);
elapsed time: 0.015871052 seconds (96 bytes allocated)
sub(x, inds)有几个原因比 sub(x, 1:N) 慢:
  • 每次访问xs[i]对应于 x[inds[i]] ;我们必须查找两个内存位置而不是一个
  • inds不按顺序,您将在访问 x 的元素时获得糟糕的缓存行为。
  • 它破坏了使用 SIMD 矢量化的能力

  • 在这种情况下,后者可能是最重要的影响。这不是 Julia 的限制;如果您用 C、Fortran 或汇编编写等效的代码,也会发生同样的事情。

    请注意,说 sum(sub(x, inds)) 仍然更快比 sum(x[inds]) ,(直到后者变成前者,当 julia 0.4 正式发布时它应该如此)。但是如果你不得不用 xs = sub(x, inds)做很多操作,在某些情况下,即使分配内存,也值得您进行复制,这样您就可以在值存储在连续内存中时利用可能的优化。

    关于julia - 在 Julia 中索引数组时避免内存分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28271308/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com