在 Julia 中使用内存映射

Use of Memory-mapped in Julia

我有一个 Julia 代码,版本 1.2,它对 10000 x 10000 Array 执行很多操作。由于 运行 代码时出现 OutOfMemory() 错误,我正在探索 运行 它的其他选项,例如内存映射。关于 Mmap.mmap 的使用,由于对 https://docs.julialang.org/en/v1/stdlib/Mmap/index.html 的解释很少,我对映射到磁盘的数组的使用有点困惑。这是我的代码的开头:

using Distances
using LinearAlgebra
using Distributions
using Mmap
data=Float32.(rand(10000,15))
Eucldist=pairwise(Euclidean(),data,dims=1)
D=maximum(Eucldist.^2)
sigma2hat=mean(((Eucldist.^2)./D)[tril!(trues(size((Eucldist.^2)./D)),-1)])
L=exp.(-(Eucldist.^2/D)/(2*sigma2hat))

L 是我要使用的 10000 x 10000 Array,所以我用

将它映射到我的磁盘
s = open("mmap.bin", "w+")
write(s, size(L,1))
write(s, size(L,2))
write(s, L)
close(s)

在那之后我应该做什么?下一步是执行 K=eigen(L) 并将其他命令应用于 K。我该怎么做?使用 K=eigen(L)K=eigen(s)? object s 的作用是什么,什么时候参与?而且,我不明白为什么我必须使用 Mmap.sync! 以及什么时候。在 eigen(L) 之后的每一行之后?在代码的末尾?我如何确定我使用的是我的磁盘 space 而不是 RAM 内存?想要一些关于内存映射的亮点,请。谢谢!

如果内存使用是一个问题,通常最好将非常大的数组重新分配给 0,或者分配给类似的类型安全的小矩阵,这样内存就可以被垃圾收集,假设你已经完成了与那些中间矩阵。之后,您只需在存储的数据文件上调用 Mmap.mmap() ,将数据的类型和维度作为 mmap 的第二个和第三个参数,然后将函数的 return 值分配给您的变量,在本例中为 L,导致 L 绑定到文件内容:

using Distances
using LinearAlgebra
using Distributions
using Mmap

function testmmap()
    data = Float32.(rand(10000, 15))
    Eucldist = pairwise(Euclidean(), data, dims=1)
    D = maximum(Eucldist.^2)
    sigma2hat = mean(((Eucldist.^2) ./ D)[tril!(trues(size((Eucldist.^2) ./ D)), -1)])
    L = exp.(-(Eucldist.^2 / D) / (2 * sigma2hat))
    s = open("./tmp/mmap.bin", "w+")
    write(s, size(L,1))
    write(s, size(L,2))
    write(s, L)
    close(s)

    # deref and gc collect
    Eucldist = data = L = zeros(Float32, 2, 2)
    GC.gc()

    s = open("./tmp/mmap.bin", "r+") # allow read and write
    m = read(s, Int)
    n = read(s, Int)
    L = Mmap.mmap(s, Matrix{Float32}, (m, n))  # now L references the file contents
    K = eigen(L)
    K
end

testmmap()
@time testmmap()  # 109.657995 seconds (17.48 k allocations: 4.673 GiB, 0.73% gc time)