memory-management - Julia 中的预分配

标签 memory-management julia

我试图通过预先分配数组来最小化 Julia 中的内存分配,如图所示 in the documentation .我的示例代码如下所示:

using BenchmarkTools

dim1 = 100
dim2 = 1000
A = rand(dim1,dim2)
B = rand(dim1,dim2)
C = rand(dim1,dim2)
D = rand(dim1,dim2)

M = Array{Float64}(undef,dim1,dim2)

function calc!(a, b, c, d, E)
     @. E = a * b * ((d-c)/d)
    nothing
end

function run_calc(A,B,C,D,M)
    for i in 1:dim2
        @views calc!(A[:,i], B[:,i], C[:,i], D[:,i], M[:,i])
    end
end
我的理解是,这基本上不应该分配,因为 M在两个函数中的任何一个之外预先分配。但是,当我对此进行基准测试时,我仍然看到很多分配:
@btime run_calc(A,B,C,D,M)

1.209 ms (14424 allocations: 397.27 KiB)


在这种情况下,我当然可以运行更简洁的
@btime @. M = A * B * ((D-C)/D)
它按预期执行很少的分配:

122.599 μs (6 allocations: 144 bytes)


但是我的实际代码更复杂,不能像这样简化,因此我想知道第一个版本哪里出了问题。

最佳答案

你没有做错任何事。目前在 Julia 中创建 View 正在分配(正如 Stefan 指出的,它比过去好得多,但在这种情况下似乎仍然发生了一些分配)。您看到的分配是由此产生的结果。
看:

julia> @allocated view(M, 1:10, 1:10)
64
您的情况是编写适当循环最简单的情况之一(我假设在您的代码中循环会更复杂,但我希望意图很明确),例如:
julia> function run_calc2(A,B,C,D,M)
           @inbounds for i in eachindex(A,B,C,D,M)
               M[i] = A[i] * B[i] * ((D[i] - C[i])/D[i])
           end
       end
run_calc2 (generic function with 1 method)

julia> @btime run_calc2($A,$B,$C,$D,$M)
  56.441 μs (0 allocations: 0 bytes)

julia> @btime run_calc($A,$B,$C,$D,$M)
  893.789 μs (14424 allocations: 397.27 KiB)

julia> @btime @. $M = $A * $B * (($D-$C)/$D);
  381.745 μs (0 allocations: 0 bytes)
编辑:Julia 版本 1.6.0-DEV.1580 上的所有时间
EDIT2:为了完整性,代码通过 @views深入到内部功能。它仍然分配(但更好)并且仍然比仅使用循环慢:
julia> function calc2!(a, b, c, d, E, i)
            @inbounds @. @views E[:,i] = a[:,i] * b[:,i] * ((d[:,i]-c[:,i])/d[:,i])
           nothing
       end
calc2! (generic function with 1 method)

julia> function run_calc3(A,B,C,D,M)
           for i in 1:dim2
               calc2!(A,B,C,D,M,i)
           end
       end
run_calc3 (generic function with 1 method)

julia> @btime run_calc3($A,$B,$C,$D,$M);
  305.709 μs (1979 allocations: 46.56 KiB)

关于memory-management - Julia 中的预分配,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65131778/

相关文章:

.NET应用程序内存使用情况-未使用的.NET以及未托管的内存和碎片数量很高

c - Free() 返回的 char 指针不会将其从内存中删除?

string - Julia:如何获得给定字符串 s 的随机排列?

javascript - javascript中的内存问题

iOS REST App 内存优化

ios - 是否可以在 Swift 中覆盖 deinit?

python - 在 Julia 中使用 PyCall.jl 时修改 Python 对象的属性

arrays - Julia 中的静态数组?

matrix - 在 Julia 中将矩阵提升为幂

floating-point - 在Julia Lang中将float转换为int