gpt4 book ai didi

python - numpy 的 memmap 写时复制模式是如何工作的?

转载 作者:行者123 更新时间:2023-12-03 17:20:19 24 4
gpt4 key购买 nike

我对 numpy 的 memmap 感到困惑使用写时复制 (mmap_mode=c) 时处理对数据的更改。由于没有将任何内容写入磁盘上的原始数组,因此我希望它必须将所有更改存储在内存中,因此如果您修改每个元素,可能会耗尽内存。令我惊讶的是,它没有。

我正在尝试减少我在共享集群上运行的机器学习脚本的内存使用量(每个实例占用的内存越少,我可以同时运行的实例越多)。我的数据是非常大的 numpy 数组(每个 > 8 Gb)。我希望使用 np.memmap使用这些具有小内存(<4Gb 可用)的阵列。

但是,每个实例可能会以不同的方式修改数据(例如,可能每次都选择以不同的方式对输入数据进行标准化)。这对存储空间有影响。如果我使用 r+模式,然后在我的脚本中规范化数组将永久更改存储的数组。

由于我不想要数据的冗余副本,而只想将原始数据存储在磁盘上,我认为我应该使用 'c'模式(写时复制)打开阵列。但是你的改变去哪里了?更改是否仅保存在内存中?如果是这样,如果我更改整个数组,我不会在小内存系统上耗尽内存吗?

这是我预计会失败的测试示例:

在大型内存系统上,创建数组:

import numpy as np
GB = 1000**3
GiB = 1024**3
a = np.zeros((50000, 20000), dtype='float32')
bytes = a.size * a.itemsize
print('{} GB'.format(bytes / GB))
print('{} GiB'.format(bytes / GiB))
np.save('a.npy', a)
# Output:
# 4.0 GB
# 3.725290298461914 GiB

现在,在只有 2 Gb 内存的机器上,这会按预期失败:
a = np.load('a.npy')

但正如预期的那样,这两个会成功:
a = np.load('a.npy', mmap_mode='r+')
a = np.load('a.npy', mmap_mode='c')

问题 1:我运行此代码时内存不足,试图修改 memmapped 数组(无论 r+/c 模式如何都失败):
for i in range(a.shape[0]):
print('row {}'.format(i))
a[i,:] = i*np.arange(a.shape[1])

为什么会失败(特别是为什么它甚至在 r+ 模式下也会失败,它可以写入磁盘)?我以为 memmap只会将数组的一部分加载到内存中吗?

问题 2:当我强制 numpy 每隔一段时间刷新一次更改时,两种 r+/c 模式都会成功完成循环。 但是怎么能c模式这样做? 没想到 flush()愿意为 c 做任何事模式?更改不会写入磁盘,因此它们保存在内存中,但不知何故,所有必须超过 3Gb 的更改不会导致内存不足错误?
for i in range(a.shape[0]):
if i % 100 == 0:
print('row {}'.format(i))
a.flush()
a[i,:] = i*np.arange(a.shape[1])

最佳答案

Numpy 在这里没有做任何聪明的事情,它只是遵循内置的 memmap模块,它有一个 access论点:

accepts one of four values: ACCESS_READ, ACCESS_WRITE, or ACCESS_COPY to specify read-only, write-through or copy-on-write memory respectively.


在 linux 上,这通过调用 mmap 来工作。系统调用

MAP_PRIVATE

Create a private copy-on-write mapping. Updates to themapping are not visible to other processes mapping the samefile, and are not carried through to the underlying file.


关于你的问题

The changes aren't written to disk, so they are kept in memory, and yet somehow all the changes, which must be over 3Gb, don't cause out-of-memory errors?


更改可能会写入磁盘,但不会写入您打开的文件。它们很可能被分页到某个地方的虚拟内存中。

关于python - numpy 的 memmap 写时复制模式是如何工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54013658/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com