【发布时间】:2026-01-28 21:25:02
【问题描述】:
我有一个在状态中存储大型numpy 数组的类。这导致multiprocessing.Pool 变得非常缓慢。这是一个 MRE:
from multiprocessing import Pool
import numpy
import time
from tqdm import tqdm
class MP(object):
def __init__(self, mat):
self.mat = mat
def foo(self, x):
time.sleep(1)
return x*x + self.mat.shape[0]
def bar(self, arr):
results = []
with Pool() as p:
for x in tqdm(p.imap(self.foo, arr)):
results.append(x)
return results
if __name__ == '__main__':
x = numpy.arange(8)
mat = numpy.random.random((1,1))
h = MP(mat)
res = h.bar(x)
print(res)
我在 CPU 上有 4 个内核,这意味着这段代码应该(并且确实)在大约 2 秒内运行。 (tqdm 将 2 秒显示为进度条,对于本示例来说,这并不是必需的)。但是,在主程序中,如果我执行mat = numpy.random.random((10000,10000)),则需要永远运行。我怀疑这是因为Pool 正在为每个工人制作mat 的副本,但我不确定这是如何工作的,因为mat 处于类的状态,并且不直接参与imap 调用.所以,我的问题是:
- 为什么会发生这种行为? (即
Pool在一个类中如何工作?它究竟腌制了什么?复制了哪些副本,以及通过引用传递了什么?) - 有什么可行的解决方法来解决这个问题?
编辑:修改foo以使用mat,这更能代表我的实际问题。
【问题讨论】:
-
x在你的主程序中有多大? -
在你的主程序中,你传递给
p.imap的函数是否需要是MP的方法,还是可以是未绑定的函数? -
@JeremyMcGibbon 好点。我想我的例子并不能很好地代表我的真正问题。所以,函数确实需要是
MP的方法,因为函数实际上是从mat读取的。 -
那么你的问题 2 没有答案,但希望我已经回答了问题 1。
标签: python numpy parallel-processing shared-memory python-multiprocessing