我試圖測量一段代碼,我使用Python的多處理程序包「並行化」,特別是使用Process函數。引入多處理隊列時執行時間增加
我有,我想並行運行兩個功能:function1
和function2
。 function1
不返回值,function2
。函數2的返回值是一個相當大的類實例。
這裏是我現有的使用隊列並行並獲得返回值碼:
import multiprocessing as mpc
...
def Wrapper(self,...):
jobs = []
q = mpc.Queue()
p1 = mpc.Process(target=self.function1,args=(timestep,))
jobs.append(p1)
p2 = mpc.Process(target=self.function2,args=(timestep,arg1,arg2,arg3,...,q))
jobs.append(p2)
for j in jobs:
j.start()
result = q.get()
for j in jobs:
j.join()
所以,這裏是我看到的問題。如果我刪除了對result = q.get()
的調用,執行Wrapper函數所需的時間顯着減少,因爲它不是從function2
返回類,但是我顯然沒有從函數中獲取我需要的數據。如果我把它放回來,運行時間會大大增加,從而表明並行化實際上比順序執行這兩個函數花費的時間更長。
下面是一些意味着包裝的執行時間,以供參考:
順序碼(即,
function1(timestep)
,res = function2(timestep,a1,a2,a3,...,None)
):10秒並行化的代碼,而無需使用一個隊列:8秒
帶隊列的並行碼:60秒
此代碼的目標是展示如何並行化一段代碼可以提高執行不必要的並行函數所需的時間。作爲參考,我使用cProfile包,生成我的代碼配置文件,並查看Wrapper運行所需的時間。
我開始對整個過程感到沮喪。它的目的是基本上加速我已經添加到內部開發的現有自定義框架中的部分程序,但是我無法實際表明我沒有增加太多開銷。
如果我看節目的總執行時間,並行化的代碼運行得更快。但是,當我深入挖掘時,我的並行代碼開始顯得需要更長的時間。
現在,我的想法是,隊列正在做某種深層複製操作,但是我找不到引用來說明這一事實,所以我假設它正在返回一個淺拷貝,對我而言,不應該要求這樣的開銷。
雖然有些令人沮喪聽到(因爲這是我害怕的東西),這是一個很好的答案。正如我試圖展示一個比較,你認爲爲並行和非並行代碼創建Manager服務器是值得的嗎?我認爲如果兩者都使用相同類型的共享對象,那麼在計算我的應用程序時,性能下降可能不太明顯。 – espais 2015-02-18 14:56:34
@espais,好吧,如果你只是爲了演示的目的而這樣做,那麼你可以爲並行和順序代碼使用'Manager'。但是如果你想對「這裏是如何平行化代碼影響其性能」做一個準確的比較,現實情況是順序代碼不需要'Manager',而並行代碼則需要。如果你只是試圖展示並行化的力量,而這段代碼是一個隨心所欲的選擇,理想情況下你會有一個需要較少共享狀態的例子,所以並行化實際上更快......(續) ) – dano 2015-02-18 16:48:48
@espais因爲現在你實際上發現,由於Python的限制,並行化這些特定的代碼實際上會傷害性能。理想情況下,你會發現你的代碼庫真的會從並行獲益,但你可能沒有任何合適的東西。 – dano 2015-02-18 16:50:02