[英]Python multiprocessing outside main module: slow computations
我有一個代碼,旨在在不是 main.py 的某個模塊的某個內部部分進行多處理。 為簡單起見,我創建了一個包含兩個文件的副本代碼:main.py 和文件 f1_mod.py。 我的 main.py 看起來像:
import os
from time import time
import f1_mod
parallel = 1
N = 10000000
if __name__ == '__main__':
if not parallel:
time_start = time()
res = f1_mod.normal_exec( N )
time_end = time()
print("-->time is ", time_end - time_start )
else:
time_start = time()
res = f1_mod.parallel_exec( N )
time_end = time()
print("-->time is ", time_end - time_start )
for j in range( 100 ):
print( res[j] )
else:
print("--> CHILD PROCESS ID: ", os.getpid() )
pass
f1_mod.py 將是:
import multiprocessing as mp
import numpy as np
def pool_worker_function( k, args ):
d = args[0]
return d["p"]*( k**2 ) + d["x"]**2
def single_thread_exec( N ):
a = list( np.linspace( 0, N, N ) )
d = { "p": 0.2, "x": 0.5 }
result = []
for k in a:
result.append( d["p"]*( k**2) + d["x"]**2 )
return result
def parallel_exec( N ):
number_processors = mp.cpu_count()
number_used_processors = number_processors - 1
#try pool map method
from itertools import repeat
pool = mp.Pool( processes = number_used_processors )
d = { "p": 0.2, "x": 0.5 }
a = list( np.linspace( 0, N, N ) )
args = ( d, )
number_tasks = number_used_processors
chuncks = []
n_chunck = int( ( len(a) - 1 )/number_tasks )
for j in range( 0, number_tasks ):
if ( j == number_tasks - 1 ):
chuncks.append( a[ j*n_chunck: ] )
else:
chuncks.append( a[ j*n_chunck: j*n_chunck + n_chunck ] )
result = pool.starmap( pool_worker_function, zip( a, repeat( args ) ) )
pool.close()
pool.join()
return result
我檢查了串行版本和並行版本都給出了相同的結果,除了串行版本比多處理版本快得多。 在我的真實代碼中,有時會出現這種情況,進入 worker function 的“args”元組實際上包含一個大的 object 數據容器,其中包含一個更大的字典,用於從中讀取數據以執行操作。 誰能解釋為什么我會觀察到這種行為(即多處理時性能緩慢)? 每次都需要將數據傳遞給工作人員 function ,實際上這使得工作人員 function 占用了大量 arguments 可能是什么減緩了 IPC 代碼給出的地方? (¿?)
使用傳遞給工作人員的參數中的“重復”,因為元組傳遞的所有 arguments 對於每個工作人員都必須相同,唯一可迭代的是列表“a”。 有誰知道如何對此進行有效的多處理? 另外,請注意,多處理不會發生在“main.py”級別,而是發生在代碼邏輯中某些模塊的“深層”函數中。 我希望能得到一些幫助,以更好地理解這種多處理是如何工作的,我在 Windows 操作系統下使用 4 核機器。 我現在知道 Windows 在使用多處理時不支持類似“fork”的行為,但是,在我的機器上運行 Ubuntu 中的代碼似乎也很慢! 謝謝!!
我對當前代碼的最佳猜測:您在pool_worker_function
中沒有做足夠的工作來抵消通信/同步的成本。
我可能錯了,但是您的代碼似乎完成了一半:從未使用過chunks
變量。 無論如何,傳遞一個大的 arrays (你的塊)可能不是最好的解決方案。
您可以嘗試將 start/len 參數傳遞給您的pool_worker_function
,然后創建數組並在那里進行計算,但我不能 100% 確定它是否足以抵消結果的通信成本。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.