【问题标题】:Julia intermediate array allocation with dots带点的 Julia 中间数组分配
【发布时间】:2021-07-03 13:04:20
【问题描述】:

我有一个 PDE 模型,我正在尝试减少分配。目前,以下行是最大的分配来源:

part2 .= r.*u .+ deriv .+ q .+ u.^3

part2derivu 是预分配的 Float64 矩阵。 rqFloat64 数字。

我的理解是使用预先分配的左侧和. 表示法应该避免分配中间临时数组,那么为什么这条线仍然是我最大的分配来源?

如果我将此行替换为以下内容并添加另一个预分配矩阵 part1,我会得到零分配,但代码的可读性要低得多。

broadcast!(*,part2,u,u,u)
broadcast!(*,part1,r,u)
broadcast!(+,part2,part2,part1,deriv,q)

【问题讨论】:

    标签: julia


    【解决方案1】:

    除非您的矩阵是一些非标准对象,它们会做一些奇怪的事情,否则您显示的操作不会分配:

    julia> part2 = rand(1000, 1000);
    
    julia> deriv = rand(1000, 1000);
    
    julia> u = rand(1000, 1000);
    
    julia> r, q = rand(2);
    
    julia> using BenchmarkTools
    
    julia> @btime $part2 .= $r .* $u .+ $deriv .+ $q .+ $u .^ 3;
      1.011 ms (0 allocations: 0 bytes)
    

    (也许您使用过@time,并在您第一次运行代码时看到了编译导致的分配?)

    【讨论】:

    • 我正在通过使用---track-allocation=user 运行 Julia 来评估分配情况,它在 .mem 文件中的这一行显示了分配情况。我很困惑,因为正如您所展示的,单独运行该行现在确实显示了分配。
    • 我对 .mem 文件的体验是,它们并不总是 100% 准确(但我不是如何生成它们的专家,所以也许更知情的人可以发表评论)。
    • 您可以尝试使用 Cthulhu.jl 之类的东西来查看是否发生隐藏类型不稳定性
    • 我仍然没有找到应该分配这行代码的原因,所以我将得出结论,@BogumiłKamiński 是正确的,即 .mem 文件不准确。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2021-02-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多