在 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)
我有一个 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)