【问题标题】:Multiprocessing - using the Managers Namespace to save memory多处理 - 使用 Managers 命名空间来节省内存
【发布时间】:2018-01-20 00:18:48
【问题描述】:

我有几个进程,每个进程都完成需要单个大型 numpy 数组的任务,这只是被读取(线程正在搜索它以寻找合适的值)。

如果每个进程都加载数据,我会收到内存错误。

因此,我试图通过使用管理器在进程之间共享相同的数组来最小化内存使用量。

但是我仍然收到内存错误。我可以在主进程中加载​​数组一次,但是当我尝试将其设置为管理器命名空间的 属性时,我收到 内存错误 .我假设管理器的行为类似于指针,并允许单独的进程(通常只能访问自己的内存)也可以访问此共享内存。但是错误提到了酸洗:

Traceback (most recent call last):
  File <PATH>, line 63, in <module>
    ns.pp = something
  File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\managers.py", line 1021, in __setattr__
    return callmethod('__setattr__', (key, value))
  File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\managers.py", line 716, in _callmethod
    conn.send((self._id, methodname, args, kwds))
  File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\connection.py", line 206, in send
    self._send_bytes(ForkingPickler.dumps(obj))
  File "C:\Program Files (x86)\Python35-32\lib\multiprocessing\reduction.py", line 50, in dumps
    cls(buf, protocol).dump(obj)
MemoryError

我假设分配给经理时实际上正在复制 numpy 数组,但我可能错了。

为了让事情变得更烦人,我在一台 32GB 内存的机器上观察内存使用情况,它在崩溃之前只会增加一点,最多可能增加 5%-10%。

谁能解释为什么将数组作为命名空间的属性会占用更多内存?以及为什么我的程序不会使用一些可用的空闲内存? (我已经阅读了namespacemanager 文档以及这些managersnamespace SO 上的线程。

我正在运行 Windows Server 2012 R2 和 Python 3.5.2 32 位。

这里有一些代码演示了我的问题(您需要使用 large.txt 的替代文件,该文件是大约 75MB 的制表符分隔字符串):

import multiprocessing
import numpy as np

if __name__ == '__main__':

    # load Price Paid Data and assign to manager
    mgr = multiprocessing.Manager()
    ns = mgr.Namespace()

    ns.data = np.genfromtxt('large.txt')
    # Alternative proving this work for smaller objects
    # ns.data = 'Test PP data'

【问题讨论】:

标签: python numpy memory out-of-memory python-multiprocessing


【解决方案1】:

经理类型是为灵活性而非效率而构建的。他们创建一个保存值的服务器进程,并且可以将代理对象返回到需要它们的每个进程。服务器和代理通过 tls 进行通信,以允许服务器和代理位于不同的机器上,但这必然意味着复制任何对象有问题。我没有一直追查源头,所以额外的副本可能在使用后被垃圾收集,但至少最初必须有一个副本。

如果你想要共享物理内存,我建议使用Shared ctypes Objects。这些实际上确实指向内存中的一个公共位置,因此速度更快,资源也更少。它们不支持全胖 python 对象所做的所有相同的事情,但可以通过创建 structs 来扩展它们来组织您的数据。

【讨论】:

  • 您建议 structs 但 ctypes 数组也适合吗?
  • 还有什么是tls?是否有您的信息的特定来源(除了文档)我可以阅读以了解更多信息?
  • @Harrydewinton source 永远不会撒谎。 tls 是transport layer security。它是一种通过套接字进行通信的通信协议(可以跨进程或通过以太网等物理层转发)
  • @Harrydewinton 看看this 部分末尾的示例。它展示了如何使用 ctypes.Structure 为您的 multiprocessing.sharedctypes.Array 命名值,以便更轻松地处理数字(而不仅仅是记住数组偏移量)
  • managers 实际上真的很酷,它允许你用任何可以安装 python 的计算机来设置一个计算集群。如果您坚持使用一台物理机器(以及一个父进程),我会坚持使用实际的共享内存。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多