4

我正在使用位於公司大型機上的虛擬機。Python多處理/線程比虛擬機上的單個處理花費的時間更長

我有4個內核分配工作,所以我試圖進入並行處理我的Python代碼。我還不熟悉它,而且我遇到了非常意外的行爲,即多處理/線程比單處理花費的時間更長。我不知道我是否做錯了什麼,或者如果問題來自我的虛擬機。

下面是一個例子:

import multiprocessing as mg 
import threading 
import math 
import random 
import time 

NUM = 4 

def benchmark(): 
    for i in range(1000000): 
    math.exp(random.random()) 

threads = [] 
random.seed() 

print "Linear Processing:" 
time0 = time.time() 
for i in range(NUM): 
    benchmark() 
print time.time()-time0 

print "Threading:" 
for P in range(NUM): 
    threads.append(threading.Thread(target=benchmark)) 
time0 = time.time() 
for t in threads: 
    t.start() 
for t in threads: 
    t.join() 
print time.time()-time0 

threads = [] 
print "Multiprocessing:" 
for i in range(NUM): 
    threads.append(mg.Process(target=benchmark)) 
time0 = time.time() 
for t in threads: 
    t.start() 
for t in threads: 
    t.join() 
print time.time()-time0 

從這樣的結果是這樣的:

Linear Processing: 
1.125 
Threading: 
4.56699991226 
Multiprocessing: 
3.79200005531 

線性處理是這裏最快的是什麼,我希望和預期的相反。 我不能確定有關加入語句應該如何執行的,所以我也做了例子與加入這樣的:

for t in threads: 
    t.start() 
    t.join() 

現在,這導致輸出是這樣的:

Linear Processing: 
1.11500000954 
Threading: 
1.15300011635 
Multiprocessing: 
9.58800005913 

現在穿線幾乎與單一處理一樣快,而多處理速度更慢。

當在任務管理器中觀察處理器負載時,即使在執行多處理時,四個虛擬內核的單獨負載也不會超過30%,因此我在此懷疑配置問題。

我想知道我是否正確地做了基準測試,如果這種行爲真的和我想的一樣奇怪。

+0

由於兩個線程不能並行執行,而是由於Python中的GIL,所以線程更慢。多處理速度較慢,因爲分叉新流程需要花費時間。如果你有更昂貴的計算併產生更少的進​​程(比如2或3,取決於CPU內核),多處理會產生更快的結果。 – alexpeits

+0

感謝您的見解。事實上,我可以創建一個多處理比線性更快的案例。 – Khris

+0

使用什麼虛擬化技術?也許有一些資源限制適用於您的虛擬機,或者您的4個虛擬CPU並不能真正轉化爲4個真正的硬件CPU內核......使用'NUM'小於實際CPU數量時,您通常應該看到CPU限制更好的性能問題。 – mata

回答

5

所以,首先,你沒有做錯什麼,當我在我的MacBook Pro運行你的榜樣,與CPython的2.7.12,我得到:

$ python test.py 
Linear Processing: 
0.733351945877 
Threading: 
1.20692706108 
Multiprocessing: 
0.256340026855 

然而,差異就更加明顯當我改變:

for i in range(1000000): 

要:

for i in range(100000000): 

的區別是更明顯的提示:

Linear Processing: 
77.5861060619 
Threading: 
153.572453976 
Multiprocessing: 
33.5992660522 

現在爲什麼線程一貫慢?由於全球解釋器鎖定。 threading模塊的唯一好處是等待I/O。您的multiprocessing示例是執行此操作的正確方法。

因此,在您的原始示例中,Linear Processing是最快的,我將這歸咎於啓動進程的開銷。當你進行少量工作時,通常可能需要更多時間來啓動4個進程並等待它們完成,而不是僅僅在單個進程中同步完成工作。使用更大的工作量來更實際地進行基準測試。

+0

感謝您的編輯@馬蒂諾 – Will

+1

您可以將「線性處理」移動到代碼塊嗎?我嘗試編輯自己,但它說我需要編輯更多的字符,但這已經是一個很好的職位。 – horta

+0

糟糕,沒有注意到,完成了!感謝您的客氣話 :) – Will

相關問題