2012-12-02 71 views
4

我有一個函數,說fun(a,b)這是相當昂貴,並返回一組數據。Python多處理爲昂貴的操作與二維陣列

我現在的方法是這樣的:

a = np.linspace(0,100,300) 
b = np.linspace(0,100,300) 
A,B = np.meshgrid(a,b) 
Y = np.zeros(A.shape) 

for i,av in enumerate(a): 
    for j, bv in enumerate(b): 
    Y[i,j] = fun(av,bv) 

(排序的,我不得不矇混過關的事情一點,使之適合)。無論如何,這個過程需要相當長的時間,我想知道是否有一種直接的方式來使用我的多核處理器來加快速度。

+0

也許這個問題(及其答案)可能會有所幫助:http://stackoverflow.com/a/11369155/289011 – BorrajaX

+0

在附註中,查看'numpy.ndenumerate'。它和嵌套for循環之間沒有性能差異,但它更清潔一點(對於'pool.imap'等東西來說非常方便)。 –

回答

7

有一個很好的模塊叫做multiprocessing,它是Python標準庫的一部分。它會在儘可能多的內核中產生進程,以便利用其他CPU。有一個在文檔中使用Pool對象的示例,下面是該示例的簡短版本。它將計算10個數字的平方,將工作負荷分配給工作流程並顯示結果。

簡單的工作池

from multiprocessing import Pool 

def f(x): 
    return x*x 

pool = Pool(processes=4) 
print pool.map(f, range(10)) 

輸出

[0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 

我有更多的分手您的問題到同一類型的結構的挑戰。我不得不創造一些中介職能來完成這項工作。我沒有numpy,所以我只是用列表和字典來代替你放的東西。您可以替換它們並嘗試代碼。

更復雜的情況下

from multiprocessing import Pool 
import time, pprint 

def fun(av, bv): 
    time.sleep(0.1) 
    return (av, bv) 

def data_stream(a, b): 
    for i, av in enumerate(a): 
     for j, bv in enumerate(b): 
      yield (i, j), (av, bv) 

def proxy(args): 
    return args[0], fun(*args[1]) 

a = range(100, 400, 100) 
b = range(100, 400, 100) 
Y = {} 

pool = Pool(processes=4) 
results = pool.map(proxy, data_stream(a, b)) 
for k,v in results: 
    Y[k] = v 

pprint.pprint(Y) 

輸出

{(0, 0): (100, 100), 
(0, 1): (100, 200), 
(0, 2): (100, 300), 
(1, 0): (200, 100), 
(1, 1): (200, 200), 
(1, 2): (200, 300), 
(2, 0): (300, 100), 
(2, 1): (300, 200), 
(2, 2): (300, 300)} 

性能

在這個例子中我只是把一個虛擬0.1秒延遲模擬繁重的工作。但即使在這個例子中,如果你使用processes=1運行一個池,它將在0.950s運行,其運行時間爲0.352s,運行時間爲processes=4。您可以以多種不同方式使用多處理庫。池只是一種方式。你可能想要探索這些例子和實驗。

在下面的評論之一中提到了使用chunksize參數到pool.map來幫助提高性能。對於真正掌握性能的問題有一個大概的瞭解是很重要的。基本上,所有傳遞給其他進程的數據都需要被傳遞給未使用的另一個進程,然後結果通過相同的進程返回主進程。這種進程間通信存在開銷。試驗時記住這一點。

+0

我也來分享關於多處理。除非你想花更多時間進行更深入的並行化,否則這對你來說似乎是最好的選擇。 – JonathanV

+0

你可能還會提到將'chunksize'參數增加到'pool.map'(或'pool.imap')。它經常會在執行速度上產生顯着的差異,特別是對於像numpy數組那樣訪問單個項目的開銷相對較高的情況。 –