8

我发现很多类似的问题,但没有答案。对于简单数组,有 multiprocessing.Array。对于稀疏矩阵或任何其他任意对象,我找到 manager.namespace。所以我尝试了下面的代码:

from scipy import sparse
from multiprocessing import Pool
import multiprocessing
import functools

def myfunc(x,ns):
    return ns.A[x,:]*ns.A*ns.A[:,x]

manager = multiprocessing.Manager()
Global = manager.Namespace()
pool=Pool()
Global.A=sparse.rand(10000,10000,0.5,'csr')
myfunc2=functools.partial(myfunc,ns=Global)
r=pool.map(myfunc2, range(100))

该代码有效,但效率不高。16 名工人中只有 4 名在实际工作。原因是,我猜,经理一次只允许一名工作人员访问数据。由于数据是只读的,我真的不需要锁。那么有没有更有效的方法来做到这一点?

ps,我看到人们谈论写时复制 fork()。我真的不明白它是什么,但它不起作用。如果我先生成 A 并执行 Pool(),每个进程都会有一个 A 的副本。

先感谢您。

4

1 回答 1

0

命名空间对象的属性仅在明确分配给时才会更新。这里给出了很好的解释。

编辑:查看实现(在 中multiprocessing/managers.py),它似乎没有使用共享内存。它只是腌制对象并在请求时将它们发送给孩子。这可能就是为什么它需要这么长时间。

您是否有机会创建一个具有比您的 CPU 内核更多的工人的池?(即使用构造函数的processes参数Pool。)这通常不是一个好主意。

您可以尝试其他几件事;

  • 将稀疏矩阵写入文件,让每个工作进程读取文件。操作系统可能会将文件放入其缓冲区缓存中,因此其性能可能比您想象的要好得多。
  • 一个可能的改进是使用 mmap 模块使用内存映射文件。
于 2013-11-05T00:13:35.087 回答