julia,为什么函数内部的循环会发生内存分配?

xea*_*its 3 performance memory-management julia

在内存分配报告中julia --track-allocation=user,最大分配是在这个函数中:

        - function fuzzy_dot_square( v::Array{Int64, 1} )
        -     dot_prod = zero(Int64)
7063056168     for i::Int64 in 2:28
        0         dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i+28])# / 4 # no "top" pixel
        -     end
        0     for i in 29:(28*27) # compiler should literate 28*27
        0         dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i-28] + v[i+28])# / 5 # all pixels
        -     end
        0     for i in (28*27):(28*28 - 1)
        0         dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i-28])# / 4 # no "bottom" pixel
        -     end
        -
        0     return dot_prod
        - end
Run Code Online (Sandbox Code Playgroud)

- 它是矢量的"模糊点积"平方,表示像素图像28乘28(数字图像的已知MNIST数据集).

为什么分配在那里发生?据我所知,这dot_prod是唯一要分配的东西.但该报告首先指出......

我也尝试用repl复制它:

v = Array{Int64,1}(1:100)
dot_prod = zero(Int64)
@allocated for i in 2:28
    dot_prod += v[i]
end
Run Code Online (Sandbox Code Playgroud)

- 我收到以下错误@allocated for ...:

ERROR: UndefVarError: dot_prod not defined
 in macro expansion at ./REPL[3]:2 [inlined]
 in (::##1#f#1)() at ./util.jl:256
Run Code Online (Sandbox Code Playgroud)

@time宏正常工作,所以有可能是一些bug的@allocated?我有julia 0.5.0.

Fen*_*ang 8

这是一个限制--track-allocation=user.没有类型不稳定,也没有分配.

julia> function fuzzy_dot_square(v)
           dot_prod = zero(eltype(v))
           for i in 2:28
               dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i+28])# / 4 # no "top" pixel
           end
           for i in 29:(28*27) # compiler should literate 28*27
               dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i-28] + v[i+28])# / 5 # all pixels
           end
           for i in (28*27):(28*28 - 1)
               dot_prod += v[i]*(v[i] + v[i-1] + v[i+1] + v[i-28])# / 4 # no "bottom" pixel
           end
           return dot_prod
       end
fuzzy_dot_square (generic function with 1 method)

julia> const xs = [1:28^2;];

julia> @allocated fuzzy_dot_square(xs)
0
Run Code Online (Sandbox Code Playgroud)

另见Julia 文档中的这段话:

在解释结果时,有一些重要的细节.在用户设置下,由REPL代码本身发生的事件,直接从REPL调用的任何函数的第一行将显示分配.更重要的是,JIT编译还增加了分配计数,因为Julia的编译器大部分是用Julia编写的(并且编译通常需要内存分配).建议的过程是通过执行要分析的所有命令强制编译,然后调用Profile.clear_malloc_data()来重置所有分配计数器.最后,执行所需的命令并退出Julia以触发生成.mem文件.

有关详细信息,请参阅此Julia问题.