gpt4 book ai didi

python - 在多处理进程之间共享大型只读 Numpy 数组

转载 作者:IT老高 更新时间:2023-10-28 21:32:31 33 4
gpt4 key购买 nike

我有一个 60GB 的 SciPy 数组(矩阵),我必须在 5+ 个 multiprocessing Process 对象之间共享。我看过 numpy-sharedmem 并阅读了 this discussion在 SciPy 列表中。似乎有两种方法 - numpy-sharedmem 并使用 multiprocessing.RawArray() 并将 NumPy dtypes 映射到 ctype s。现在,numpy-sharedmem 似乎是要走的路,但我还没有看到一个好的引用示例。我不需要任何类型的锁,因为数组(实际上是矩阵)将是只读的。现在,由于它的大小,我想避免复制。 听起来正确的方法是将数组的 only 副本创建为 sharedmem 数组,然后将其传递给 处理 对象?几个具体问题:

  1. 将 sharedmem 句柄实际传递给 sub-Process()es 的最佳方式是什么?我需要一个队列来传递一个数组吗?管道会更好吗?我可以将它作为参数传递给 Process() 子类的 init(我假设它是腌制的)吗?

  2. 在我上面链接的讨论中,提到 numpy-sharedmem 不是 64 位安全的?我肯定使用了一些不可 32 位寻址的结构。

  3. RawArray() 方法是否存在权衡?更慢、更麻烦?

  4. numpy-sharedmem 方法是否需要任何 ctype-to-dtype 映射?

  5. 有没有人有这样的开源代码示例?我是一个动手能力很强的人,如果没有任何好的例子可以看,很难做到这一点。

如果我可以提供任何其他信息来帮助其他人澄清这一点,请发表评论,我会添加。谢谢!

这需要在 Ubuntu Linux 和也许 Mac OS 上运行,但可移植性并不是一个大问题。

最佳答案

如果您使用的是 Linux(或任何符合 POSIX 的系统),则可以将此数组定义为全局变量。 multiprocessing 在 Linux 上启动新子进程时使用 fork()。一个新生成的子进程会自动与其父进程共享内存,只要它不改变它(copy-on-write 机制)。

既然你说“我不需要任何类型的锁,因为数组(实际上是一个矩阵)将是只读的”,利用这种行为将是一种非常简单但非常有效的方法:所有 child 当读取这个大型 numpy 数组时,进程将访问物理内存中的相同数据。

不要将您的数组交给 Process() 构造函数,这将指示 multiprocessing 将数据 pickle 给子进程,这在您的情况下,这将是非常低效或不可能的。在 Linux 上,在 fork() 之后,子节点是使用相同物理内存的父节点的精确副本,因此您需要做的就是确保“包含”矩阵的 Python 变量是可访问的从您移交给 Process()target 函数中。这通常可以通过“全局”变量来实现。

示例代码:

from multiprocessing import Process
from numpy import random


global_array = random.random(10**4)


def child():
print sum(global_array)


def main():
processes = [Process(target=child) for _ in xrange(10)]
for p in processes:
p.start()
for p in processes:
p.join()


if __name__ == "__main__":
main()

在不支持 fork() 的 Windows 上 - multiprocessing 正在使用 win32 API 调用 CreateProcess。它从任何给定的可执行文件创建一个全新的进程。这就是为什么在 Windows 上,如果需要在父进程运行时创建的数据,需要将数据腌制给子进程。

关于python - 在多处理进程之间共享大型只读 Numpy 数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17785275/

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