問題是你正在使用啞元。即多線程,而不是多處理。多線程不會使CPU綁定的任務更快,但只有I/O綁定的任務。
再試一次multiprocessing.Pool,你應該有更多的成功。
multiprocessing.dummy in Python is not utilising 100% cpu
你也需要以某種方式塊你輸入序列到子序列,以做好每一道工序做足夠的計算方法,這是值得的。
我把這個解決方案。看到你只需要在主執行時調用多處理池,問題是Python會啓動執行每個映射的子引擎。
import time
from multiprocessing import Pool as ThreadPool
def square(x):
return x*x
def squareChunk(chunk):
return [square(x) for x in chunk]
def chunks(l, n):
n = max(1, n)
return (l[i:i+n] for i in range(0, len(l), n))
def flatten(ll):
lst = []
for l in ll:
lst.extend(l)
return lst
if __name__ == '__main__':
start_time = time.time()
r1 = range(10000000)
nProcesses = 100
chunked = chunks(r1, int(len(r1)/nProcesses)) #split original list in decent sized chunks
pool = ThreadPool(4)
results = flatten(pool.map(squareChunk, chunked))
pool.close()
pool.join()
print("--- Parallel map %g seconds ---" % (time.time() - start_time))
start_time = time.time()
r2 = range(10000000)
squareChunk(r2)
print("--- Serial map %g seconds ---" % (time.time() - start_time))
我碰到下面的打印輸出:
--- Parallel map 3.71226 seconds ---
--- Serial map 2.33983 seconds ---
現在的問題是不應該的並行地圖更快?
這可能是整個組塊會影響我們的效率。但是也可能是當串行處理運行後引擎更「熱身」。於是我轉身測量:
import time
from multiprocessing import Pool as ThreadPool
def square(x):
return x*x
def squareChunk(chunk):
return [square(x) for x in chunk]
def chunks(l, n):
n = max(1, n)
return (l[i:i+n] for i in range(0, len(l), n))
def flatten(ll):
lst = []
for l in ll:
lst.extend(l)
return lst
if __name__ == '__main__':
start_time = time.time()
r2 = range(10000000)
squareChunk(r2)
print("--- Serial map %g seconds ---" % (time.time() - start_time))
start_time = time.time()
r1 = range(10000000)
nProcesses = 100
chunked = chunks(r1, int(len(r1)/nProcesses)) #split original list in decent sized chunks
pool = ThreadPool(4)
results = flatten(pool.map(squareChunk, chunked))
pool.close()
pool.join()
print("--- Parallel map %g seconds ---" % (time.time() - start_time))
現在我得到:
--- Serial map 4.176 seconds ---
--- Parallel map 2.68242 seconds ---
所以它不是那麼清楚一方或另一方是否更快。但是如果你想做多處理,你必須考慮創建線程的開銷實際上是否比你期望的更快。你碰到緩存局部性問題等。
https://wiki.python.org/moin/GlobalInterpreterLock – niemmi
另外,你不是多處理,你是multi_threading_。 '多。dummy'只是線程庫的一個包裝。 https://docs.python.org/2/library/multiprocessing.html#module-multiprocessing.dummy。這就是GIL與此相關的原因。 –
@niemmi嗯,但這是我創建的一個過程,而不是一個線程。糾正我,如果我錯了。 GIL在您創建多個線程時適用。就我所知,多個進程可以在python中使用多個內核。 – Rishabh