我正在顺序地对3个不同的numpy 2D数组执行一些大型计算。阵列很大,每个25000x25000。每次计算都需要很长时间,所以我决定在服务器上的3个CPU内核上并行运行其中的3个。我遵循标准的多处理指南并创建了2个进程和一个worker函数。两个计算正在通过这两个进程运行,第三个计算在本地运行而没有单独的进程。我传递巨大的数组作为过程的参数,如:
p1 = Process(target = Worker, args = (queue1, array1, ...)) # Some other params also going
p2 = Process(target = Worker, args = (queue2, array2, ...)) # Some other params also going
Worker函数在队列中附加的列表中发回两个numpy向量(1D数组),如:
queue.put([v1, v2])
我没有使用multiprocessing.pool
但令人惊讶的是,我没有获得加速,实际上运行速度慢了3倍。通过大型阵列需要时间吗?我无法弄清楚发生了什么。我应该使用共享内存对象而不是传递数组吗?
如果有人可以提供帮助,我将感激不尽。
谢谢。
答案 0 :(得分:1)
以下是使用np.memmap
和Pool
的示例。看到您可以定义进程数和工作数。在这种情况下,您无法控制队列,这可以使用multiprocessing.Queue
:
from multiprocessing import Pool
import numpy as np
def mysum(array_file_name, col1, col2, shape):
a = np.memmap(array_file_name, shape=shape, mode='r+')
a[:, col1:col2] = np.random.random((shape[0], col2-col1))
ans = a[:, col1:col2].sum()
del a
return ans
if __name__ == '__main__':
nop = 1000 # number_of_processes
now = 3 # number of workers
p = Pool(now)
array_file_name = 'test.array'
shape = (250000, 250000)
a = np.memmap(array_file_name, shape=shape, mode='w+')
del a
cols = [[shape[1]*i/nop, shape[1]*(i+1)/nop] for i in range(nop)]
results = []
for c1, c2 in cols:
r = p.apply_async(mysum, args=(array_file_name, c1, c2, shape))
results.append(r)
p.close()
p.join()
final_result = sum([r.get() for r in results])
print final_result
如果可能,您可以使用共享内存并行处理获得更好的性能。请参阅此相关问题:
答案 1 :(得分:1)
我的问题似乎已经解决了。我正在使用一个django模块,我在里面调用multiprocessing.pool.map_async。我的worker函数是类本身的一个函数。那就是问题所在。多进程不能在另一个进程内调用同一个类的函数,因为子进程不共享内存。所以在子进程内部没有该类的实时实例。可能这就是它没有被调用的原因。据我所知。我从类中删除了该函数,并将其放在同一个文件中但在类之外,就在类定义开始之前。有效。我也获得了适度的加速。还有一件事是面对同样问题的人请不要阅读大型数组并在进程之间传递。酸洗和取消会花费很多时间,你不会加速而是速度下降。尝试读取子进程本身内的数组。
如果可能的话请使用numpy.memmap数组,它们非常快。