2015-11-18 79 views
14

我想在一個簡單的例子上運行一個並行循環。
我在做什麼錯?寫一個並行循環

from joblib import Parallel, delayed 
import multiprocessing 

def processInput(i): 
     return i * i 

if __name__ == '__main__': 

    # what are your inputs, and what operation do you want to 
    # perform on each input. For example... 
    inputs = range(1000000)  

    num_cores = multiprocessing.cpu_count() 

    results = Parallel(n_jobs=4)(delayed(processInput)(i) for i in inputs) 

    print(results) 

與代碼的問題是,當在Python 3在Windows環境中執行時,它蟒蛇執行並行作業的num_cores實例,但只有一個是積極的。這不應該是這種情況,因爲處理器的活動應該是100%而不是14%(在i7-8邏輯核心下)。

爲什麼額外的實例沒有做任何事情?

+0

您是否收到任何錯誤消息?它對我來說運行良好......。縮進應該是4個空格而不是一個... –

+0

我有同樣的問題。問題是代碼只能運行在一個核心而不是n核心上。 –

回答

17

繼續您的要求提供工作多處理代碼,我建議你使用pool_map(如果延遲的功能不重要),我會給你一個例子,如果你的python3的工作值得一提,你可以使用starmap。 另外值得一提的是,如果返回結果的順序不必與輸入順序相對應,則可以使用map_sync/starmap_async。

import multiprocessing as mp 

def processInput(i): 
     return i * i 

if __name__ == '__main__': 

    # what are your inputs, and what operation do you want to 
    # perform on each input. For example... 
    inputs = range(1000000) 
    # removing processes argument makes the code run on all available cores 
    pool = mp.Pool(processes=4) 
    results = pool.map(processInput, inputs) 
    print(results) 
+0

我喜歡這個簡單,所以我試了一下。我得到一個TypeError:無法序列化'_io.TextIOWrapper'對象。我的功能非常複雜,我沒有時間深入瞭解它,只是關於您是否具有複雜功能的評論,這可能無法正常工作 – Nick

+0

序列化是每個多進程程序的主要部分。爲了嘗試和緩解這些問題,我建議檢查你的複雜功能,並檢查它的哪一部分確實需要多處理解決方案,並嘗試將它從複雜函數中解耦,這將簡化序列化,甚至可能使其不必要。 – Fanchi

2

在Windows上,多處理模塊使用'spawn'方法來啓動多個python解釋器進程。這比較慢。並行嘗試在運行代碼時很聰明。特別是,它試圖調整批量大小,因此批量執行需要大約半秒。 (參見https://pythonhosted.org/joblib/parallel.html的參數的batch_size)

processInput()函數運行如此之快,並行確定它是更快地在一個處理器上串聯運行的作業比加速旋轉多個Python解釋和並行運行的代碼。

如果您想強制您的示例在多個內核上運行,請嘗試將batch_size設置爲1000或使processInput()更復雜,以便執行時間更長。

編輯:工作例如在Windows上,顯示在使用多個進程(我使用Windows 7):

from joblib import Parallel, delayed 
from os import getpid 

def modfib(n): 
    # print the process id to see that multiple processes are used, and 
    # re-used during the job. 
    if n%400 == 0: 
     print(getpid(), n) 

    # fibonacci sequence mod 1000000 
    a,b = 0,1 
    for i in range(n): 
     a,b = b,(a+b)%1000000 
    return b 

if __name__ == "__main__": 
    Parallel(n_jobs=-1, verbose=5)(delayed(modfib)(j) for j in range(1000, 4000)) 
+0

你能否提出一個代碼修改,以便任務能夠並行有效地執行?由於上面的代碼是作爲joblib使用的示例給出的,因此應該有一個實際可行的示例。 –