在共享内存

时间:2017-04-23 16:11:18

标签: python arrays multiprocessing python-multiprocessing

我正在使用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

现在我有两个问题:

  1. 为什么这段代码甚至会写入光盘?为什么不将它全部存储在内存中?
  2. 我该如何解决这个问题?我可以让Python将它全部存储在RAM中而无需将其写入HDD吗?或者我可以更改写入此阵列的硬盘吗?
  3. 编辑:我在网上发现了一些内容,表明该数组存储在“共享内存”中。但是/dev/shm设备有足够多的可用空间作为上面代码填充的/dev/sda1Here是此代码的strace日志的(相关部分)。

    编辑#2 :我认为我找到了解决此问题的方法。通过查看源代码,我发现multiprocessing尝试在目录中创建临时文件,该文件通过使用

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

    在脚本开头手动设置此值

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

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

1 个答案:

答案 0 :(得分:0)

这些数据大于 500GB。在我的机器上,shared_data_basesys.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 不是一个大分区。