python - 多处理中的共享内存对象

标签 python numpy parallel-processing multiprocessing shared-memory

假设我有一个大内存 numpy 数组,我有一个函数 func 将这个巨大的数组作为输入(连同其他一些参数)。不同参数的func可以并行运行。例如:

def func(arr, param):
    # do stuff to arr, param

# build array arr

pool = Pool(processes = 6)
results = [pool.apply_async(func, [arr, param]) for param in all_params]
output = [res.get() for res in results]

如果我使用多处理库,那么这个巨大的数组将被多次复制到不同的进程中。

有没有办法让不同的进程共享同一个数组?这个数组对象是只读的,永远不会被修改。

更复杂的是,如果arr不是一个数组,而是一个任意的python对象,有没有办法共享呢?

[编辑]

我阅读了答案,但我仍然有点困惑。由于 fork() 是写时复制,因此在 python 多处理库中生成新进程时,我们不应该调用任何额外的成本。但是以下代码表明存在巨大的开销:

from multiprocessing import Pool, Manager
import numpy as np; 
import time

def f(arr):
    return len(arr)

t = time.time()
arr = np.arange(10000000)
print "construct array = ", time.time() - t;


pool = Pool(processes = 6)

t = time.time()
res = pool.apply_async(f, [arr,])
res.get()
print "multiprocessing overhead = ", time.time() - t;

输出(顺便说一下,随着数组大小的增加,成本也会增加,所以我怀疑仍然存在与内存复制相关的开销):

construct array =  0.0178790092468
multiprocessing overhead =  0.252444982529

如果我们不复制数组,为什么会有这么大的开销?共享内存为我节省了哪些部分?

最佳答案

如果您使用的操作系统使用写时复制 fork() 语义(就像任何常见的 unix 一样),那么只要您从不更改您的数据结构,它就可供所有人使用子进程而不占用额外的内存。你不必做任何特别的事情(除非绝对确保你不改变对象)。

可以为你的问题做的最有效的事情是将你的数组打包成一个有效的数组结构(使用 numpyarray ),将其放在共享内存中,用 multiprocessing.Array 包装它,然后将其传递给您的函数。 This answer shows how to do that .

如果你想要一个可写共享对象,那么你需要用某种同步或锁定来包装它。 multiprocessing 提供 two methods of doing this :一个使用共享内存(适用于简单值、数组或 ctypes)或 Manager 代理,其中一个进程持有内存,一个管理器仲裁访问它来自其他进程(甚至通过网络)。

Manager 方法可用于任意 Python 对象,但会比使用共享内存的等效方法慢,因为对象需要序列化/反序列化并在进程之间发送。

有一个 wealth of parallel processing libraries and approaches available in Pythonmultiprocessing 是一个优秀且全面的库,但如果您有特殊需求,也许其他方法之一可能会更好。

关于python - 多处理中的共享内存对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10721915/

相关文章:

java - 如何确定硬件线程数

python - 将 DataFrameGroupBy 对象中的每个分组列转换为列表

python - 如何从一堆图像中裁剪具有不同位置的相同大小的图像 block ?

python - 如何在 Python 中计算分解 A=P[I_r,0;0,0]Q?

C++ 并行编程函数调用

linux - Linux shell 中的真正并行性

python - 不稳定的 TCP 接收时间

python - 在简单列表中查找特定字符串

python - Pyspark 将结构数组转换为字符串

python - 通过 numpy where 查找索引