在共享内存中使用 Multiprocessing.Array 时没有剩余空间

Posted

技术标签:

【中文标题】在共享内存中使用 Multiprocessing.Array 时没有剩余空间【英文标题】:No space left while using Multiprocessing.Array in shared memory 【发布时间】:2017-09-20 06:34:18 【问题描述】:

我正在使用 Python 的多处理功能在大约 500GB RAM 的机器上并行运行我的代码。为了在不同的工作人员之间共享一些数组,我创建了一个 Array 对象:

N = 150
ndata = 10000
sigma = 3
ddim = 3

shared_data_base = multiprocessing.Array(ctypes.c_double, ndata*N*N*ddim*sigma*sigma)
shared_data = np.ctypeslib.as_array(shared_data_base.get_obj())
shared_data = shared_data.reshape(-1, N, N, ddim*sigma*sigma)

这对于sigma=1 非常有效,但对于sigma=3,设备的一个硬盘驱动器会慢慢被填满,直到没有可用空间,然后进程失败并出现以下异常:

OSError: [Errno 28] No space left on device

现在我有 2 个问题:

    为什么这段代码甚至可以向光盘写入任何内容?为什么不全部存储在内存中? 我该如何解决这个问题?我可以让 Python 将其完全存储在 RAM 中而不将其写入 HDD 吗?或者我可以更改写入此阵列的硬盘吗?

编辑:我在网上找到了一些建议,该数组存储在“共享内存”中。但是/dev/shm 设备有更多可用空间,因为/dev/sda1 由上面的代码填充。 Here 是这段代码的(相关部分)strace 日志。

Edit #2:我想我已经找到了解决这个问题的方法。通过查看源代码,我发现multiprocessing 尝试在使用确定的目录中创建一个临时文件

process.current_process()._config.get('tempdir')

在脚本开头手动设置此值

from multiprocessing import process
process.current_process()._config['tempdir'] =  '/data/tmp/'

似乎正在解决这个问题。但我认为这不是解决问题的最佳方法。那么:有没有其他建议如何处理呢?

【问题讨论】:

strace 下运行它,看看发生了什么。 顺便说一句,500G 内存在哪里? :) 错误代码也可能有误。真正的意思是内存不足。 IE。 python 库滥用该代码。 我的猜测是multiprocessing.Array() 使用/dev/shm,它(至少在 Linux 上)被限制为可用 RAM 的一半(检查 df -kh /dev/shm)。看看here 如何增加它(如果这是限制因素)。 您确定 sizeof(c_double) * ndata*N*N*ddim*sigma*sigma 适合您的 RAM 吗? 【参考方案1】:

这些数据大于 500GB。 shared_data_base 在我的机器上 sys.getsizeof() 将是 826.2GB,pympler.asizeof.asizeof() 将是 1506.6GB。即使它们只有 500GB,您的机器也需要一些内存才能运行。这就是数据要写入磁盘的原因。

import ctypes
from pympler.asizeof import asizeof
import sys


N = 150
ndata = 10000
sigma = 3
ddim = 3
print(sys.getsizeof(ctypes.c_double(1.0)) * ndata*N*N*ddim*sigma*sigma)
print(asizeof(ctypes.c_double(1.0)) * ndata*N*N*ddim*sigma*sigma)

请注意,在我的机器(Debian 9)上,/tmp 是填充的位置。如果您发现必须使用磁盘,请确保使用的磁盘位置有足够的可用空间,通常 /tmp 不是一个大分区。

【讨论】:

以上是关于在共享内存中使用 Multiprocessing.Array 时没有剩余空间的主要内容,如果未能解决你的问题,请参考以下文章

multiprocessing.Manager共享内存的问题记录

python multiprocessing - 在进程之间共享类字典,随后从进程写入反映到共享内存

python进程线程:共享内存

Python共享读内存

PyTorch 1.0 中文文档:多进程包 - torch.multiprocessing

用python多进程模块multiprocessing创建的子进程如何共享内存空间?