2016-03-08 29 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