【问题标题】:Use of Memory-mapped in Julia在 Julia 中使用内存映射
【发布时间】:2019-09-03 03:00:30
【问题描述】:

我有一个 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)?对象s 的作用是什么,它什么时候参与进来?此外,我不明白为什么我必须使用Mmap.sync! 以及何时使用。在eigen(L) 之后的每一行之后?在代码的末尾?我如何确定我使用的是磁盘空间而不是 RAM 内存?想要一些关于内存映射的亮点,请。谢谢!

【问题讨论】:

  • 任何时候您重复发布,交叉链接到您的其他人:discourse.julialang.org/t/use-of-memory-mapped-i-o/28311。这是尊重他人时间的礼貌方式。
  • 只是为了确保我可以向最多人展示我的问题并收集很多建议,因为堆栈溢出和 Julia 论坛的所有用户不一定相同
  • 是的,但人们通常会说基本相同的话。如果他们可以阅读某人已经写过的内容,他们就可以只关注他们建议的新颖部分。为他们节省一些时间,而且这样做不会造成任何损失。
  • 好的 :-) 下次会考虑到这一点 ;-)

标签: out-of-memory julia memory-mapping


【解决方案1】:

如果内存使用是一个问题,通常最好将非常大的数组重新分配给 0,或类似的类型安全的小矩阵,以便内存可以被垃圾收集,假设你已经完成了这些中间矩阵。之后,您只需在存储的数据文件上调用 Mmap.mmap(),将数据的类型和维度作为 mmap 的第二个和第三个参数,然后将函数的返回值分配给您的变量,在本例中为 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)

【讨论】:

  • 好的,谢谢 :-) 我知道它比较慢,但是当我在没有内存映射的情况下运行整个代码时出现内存错误,所以我别无选择 ;-) 这只是我的代码的开始
  • 我喜欢将大型数组重新分配为 0 的建议!大多数时候,我不再需要中间矩阵了!
猜你喜欢
  • 2015-06-14
  • 1970-01-01
  • 2014-08-01
  • 2015-08-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多