Julia 中的奇怪分配

use*_*278 5 memory julia

考虑这个函数

function test_function(state, M, new_number)
    M[state..., 1] = new_number
end
Run Code Online (Sandbox Code Playgroud)

在我的程序中,我想多次运行此函数,每次参数都是新的(有时由用户提供)。

为了测试这个函数的内存分配和速度,我写了这个循环


function test_for_loop(loop_num)
    state = [1, 1, 1 ]
    M     = randn(10,10,10,10)
    new_number = 3.0
    for i in 1:loop_num
        test_function(state, M, new_number)
    end 
end 

Run Code Online (Sandbox Code Playgroud)

请注意,编写纯粹是为了测试多次应用test_for_loop的效率。test_function实际上,在每个应用程序中,stateM、 和new_number都是事先未知的。

我用@allocated查找内存分配。随着我的增加loop_num,内存分配也增加了。我不知道为什么所以我用了--track-allocation. 事实证明M[state...] = new_number占用了大量的内存分配。有人可以解释一下为什么吗?为什么它分配额外的内存,以及如何减少内存分配,使其不随 增加loop_num

Bog*_*ski 6

原因是:

state = [1, 1, 1]
Run Code Online (Sandbox Code Playgroud)

这是一个向量,没有指定它的类型有多长。

将其更改为例如元组(因为元组已知编译时大小):

state = (1, 1, 1)
Run Code Online (Sandbox Code Playgroud)

分配问题将得到解决:

julia> function test_for_loop(loop_num)
           state = (1, 1, 1)
           M     = randn(10,10,10,10)
           new_number = 3.0
           for i in 1:loop_num
               test_function(state, M, new_number)
           end
       end
test_for_loop (generic function with 1 method)

julia> @time test_for_loop(10^8)
  0.118755 seconds (2 allocations: 78.188 KiB)
Run Code Online (Sandbox Code Playgroud)

  • 与“Vector”相比,使用“Tuple”可显着提高运行时间。在这种情况下,使用 StaticArrays.jl 并不能改善当前 Julia 1.8 上的情况。然而,它可能是因为集合大小信息被编码在类型中(因此在 Julia 的未来版本中,如果编译器中进行了适当的优化,它的运行速度可能与“Tuple”一样快)。在编译时已知的是值的类型(但不是值本身)。因此编译器只知道类型中编码的信息。 (3认同)