2016-03-08 85 views
5

我有一个问题,这是与此类似:Python的多处理和共享numpy的阵列

import numpy as np 

C = np.zeros((100,10)) 

for i in range(10): 
    C_sub = get_sub_matrix_C(i, other_args) # shape 10x10 
    C[i*10:(i+1)*10,:10] = C_sub 

因此,显然没有必要,运行此作为串行计算,因为每个子矩阵可以被独立计算。 我想使用多处理模块并为for循环创建最多4个进程。 我阅读了一些关于多处理的教程,但无法弄清楚如何使用它来解决我的问题。

感谢您的帮助

+2

为了多得性能改进的计算** **必须采取显著时间。因为多处理将*序列化*数据,将其发送到子进程,对其进行反序列化并执行计算,序列化结果,将其发送回主进程并最终反序列化它。序列化/反序列化需要相当长的时间,加上进程间通信也不是那么快。如果'get_sub_matrix'实际上只是一些矩阵访问,你就不会获得任何加速。 – Bakuriu

+0

这只是为了说明的目的。最后,我的矩阵的维数约为100000 x 20000,但get_sub_matrix_C更为重要的是速度较慢,我认为我无法更快地完成该功能。 – RoSt

+0

get_sub_matrix_C是否需要访问所有矩阵或只是子矩阵?因为如果需要它,每个子进程的大矩阵的一个副本的序列化将非常耗时且耗费内存。 – eguaio

回答

4

一个简单的方法来并行化代码将使用的过程Pool

pool = multiprocessing.Pool() 
results = pool.starmap(get_sub_matrix_C, ((i, other_args) for i in range(10))) 

for i, res in enumerate(results): 
    C[i*10:(i+1)*10,:10] = res 

我用starmap因为get_sub_matrix_C函数有多个参数(starmap(f, [(x1, ..., xN)])电话f(x1, ..., xN))。

但请注意,序列化/反序列化可能需要大量时间和空间,因此您可能必须使用更低级别的解决方案来避免这种开销。


它看起来像你正在运行一个过时的版本的蟒蛇。你可以用普通map取代starmap但你必须提供一个函数,它接受一个参数:

def f(args): 
    return get_sub_matrix_C(*args) 

pool = multiprocessing.Pool() 
results = pool.map(f, ((i, other_args) for i in range(10))) 

for i, res in enumerate(results): 
    C[i*10:(i+1)*10,:10] = res 
+0

感谢您的回答。不幸的是我无法测试它,因为我没有星图。可能我正在使用过时的多处理版本?版本:0.70a1 – RoSt

+0

@RoSt您可以使用'map'并修改函数来接受单个参数。我编辑了答案来添加这个解决方案。 – Bakuriu

+0

感谢您提供简单直接的解决方案。它工作正常。我会投你一票,但我自己的声望<15,对不起... – RoSt

0

下面的配方也许可以完成这项工作。随意问。

import numpy as np 
import multiprocessing 

def processParallel(): 

    def own_process(i, other_args, out_queue): 
     C_sub = get_sub_matrix_C(i, other_args) 
     out_queue.put(C_sub)    

    sub_matrices_list = [] 
    out_queue = multiprocessing.Queue() 
    other_args = 0 
    for i in range(10): 
     p = multiprocessing.Process(
          target=own_process, 
          args=(i, other_args, out_queue)) 
     procs.append(p) 
     p.start() 

    for i in range(10): 
     sub_matrices_list.extend(out_queue.get()) 

    for p in procs: 
     p.join() 

    return sub_matrices_list  

C = np.zeros((100,10)) 

result = processParallel() 

for i in range(10): 
    C[i*10:(i+1)*10,:10] = result[i] 
+0

感谢您的回答。我试过了,但是我得到了令人困惑的结果。同样的条目一遍又一遍地重复着。 – RoSt

+1

我刚纠正了错误,抱歉。无论如何,其他答案似乎更简洁实用。我也会自己试试! :) – eguaio