2012-06-26 153 views
4

我有一個龐大的數據集,我必須計算它的每一個點的一系列屬性。我的代碼非常慢,我想讓它更快地並行化do循環。我希望每個處理器爲我的數據的有限子樣本計算「一系列屬性」,然後將所有屬性連接在一個數組中。 我會嘗試解釋我必須要做的一個例子。需要幫助來並行python循環

比方說,我的數據集是數組x

x = linspace(0,20,10000) 

的「財產」我希望得到的是,例如,平方根x

prop=[] 
for i in arange(0,len(x)): 
    prop.append(sqrt(x[i])) 

問題我如何平行上面的循環?假設我有4個處理器,並且我希望每個處理器計算10000/4 = 2500點的sqrt。

我試着看過一些Python模塊,如multiprocessingmpi4py,但從指南我找不到這樣一個簡單的問題的答案。

編輯

我要謝謝大家的寶貴意見和鏈接,您爲我提供。不過,我想澄清一下我的問題。無論如何,我對sqrt功能不感興趣。 我正在循環中執行一系列操作。我完全知道循環是壞的,矢量操作總是比他們更可取,但在這種情況下,我真的必須做一個循環。我不會詳細討論我的問題,因爲這會給這個問題增加不必要的複雜性。 我想分割我的循環,以便每個處理器都能完成它的一部分,這意味着我可以用每個循環的1/40來運行我的代碼40次,並且合併結果,但這將是愚蠢的。 這是一個簡單的例子

 for i in arange(0,len(x)): 
     # do some complicated stuff 

我要的是用40級的CPU來做到這一點:

​​

那是可能的,或者不使用Python?

+6

對於這個特殊的例子,你會比使用'numpy.sqrt(x)'而不是Python循環的單純因子4快得多。你的真實任務可能也是如此。 –

+1

感謝您的回答,但是我的真正任務比執行sqrt更復雜。我只是想知道爲什麼我找不到任何簡單的python循環並行化的例子。 – Brian

+6

根據我的經驗,矢量化是在99%的情況下加速數值Python循環的方法,即使它們更復雜。描述你的真實功能,我可以告訴你如何進行矢量化。 –

回答

2

我不確定這是你應該如何做的事情,因爲我期望numpy有一個更有效的方法去實現它,但是你的意思是這樣嗎?

import numpy 
import multiprocessing 

x = numpy.linspace(0,20,10000) 
p = multiprocessing.Pool(processes=4) 

print p.map(numpy.sqrt, x) 

以下是兩種解決方案的結果timeit。正如@SvenMarcach指出的那樣,然而,如果使用更昂貴的功能,多處理將開始變得更加有效。

% python -m timeit -s 'import numpy; x=numpy.linspace(0,20,10000)' 'prop=[]                   
for i in numpy.arange(0,len(x)): 
     prop.append(numpy.sqrt(x[i]))' 
10 loops, best of 3: 31.3 msec per loop 

% python -m timeit -s 'import numpy, multiprocessing; x=numpy.linspace(0,20,10000) 
p = multiprocessing.Pool(processes=4)' 'l = p.map(numpy.sqrt, x)' 
10 loops, best of 3: 102 msec per loop 

在斯文的要求,這裏是l = numpy.sqrt(x)其結果是比任何替代品更快顯著

% python -m timeit -s 'import numpy; x=numpy.linspace(0,20,10000)' 'l = numpy.sqrt(x)' 
10000 loops, best of 3: 70.3 usec per loop 
+1

'multiprocessing'方法比較慢,因爲每次迭代執行的函數都是相當簡單的。如果你在每次迭代中都有一個「胖」函數,你實際上會看到一個加速。在時機中加入'l = numpy.sqrt(x)'也會很有趣。 –

+0

@SvenMarnach這是一個很好的觀點,我唯一使用'multiprocessing'的時間很多,就像獲取很多網頁一樣,它顯然要快得多。我沒有考慮過sqrt實際上是一個相當微不足道的函數,我試圖編輯我的帖子來反映這一點,以及添加'numpy.sqrt(x)'的結果。 –

+1

請注意,最後的解決方案實際上比普通Python循環快450倍。它不是在另外兩個之間!這又是我上面評論的重點。 –

3

並行並不重要,但是您可能會發現numexpr有用。

對於數值工作,你真的應該看看numpy的給你(vectorize和類似)的實用工具,這些給你通常是一個好加速的基礎上工作。

對於更復雜的非數值情況,您可以使用multiprocessing(請參閱註釋)。


在一個旁註,多線程是更加非平凡與Python比用其他語言,是CPython的具有Global Interpreter Lock (GIL)其中不允許的Python代碼兩段同時在相同的解釋器運行(即沒有真正的多線程純Python代碼)。對於I/O和繁重的計算,不過第三方庫傾向於釋放該鎖,因此有限的多線程是可能的。

這增加了必須互斥共享數據訪問和類似的常見多線程滋擾。

+0

感謝您的鏈接。但我希望找到一個python中最簡單的並行循環例子的鏈接。 – Brian

+1

@Matteo:這裏你去:http://docs.python.org//library/multiprocessing.html#using-a-pool-of-workers –

+1

謝謝,但從這個例子,它不是很清楚(至少不是對我來說很清楚)我如何在每個處理器之間分配任務。 – Brian