[英]How to find ideal number of parallel processes to run with python multiprocessing?
試圖找出使用python multiprocessing運行的正確數量的並行進程。
以下腳本在 8 核 32 GB (Ubuntu 18.04) 機器上運行。 (以下測試時只有系統進程和基本用戶進程在運行。)
使用以下內容測試了multiprocessing.Pool
和apply_async
:
from multiprocessing import current_process, Pool, cpu_count
from datetime import datetime
import time
num_processes = 1 # vary this
print(f"Starting at {datetime.now()}")
start = time.perf_counter()
print(f"# CPUs = {cpu_count()}") # 8
num_procs = 5 * cpu_count() # 40
def cpu_heavy_fn():
s = time.perf_counter()
print(f"{datetime.now()}: {current_process().name}")
x = 1
for i in range(1, int(1e7)):
x = x * i
x = x / i
t_taken = round(time.perf_counter() - s, 2)
return t_taken, current_process().name
pool = Pool(processes=num_processes)
multiple_results = [pool.apply_async(cpu_heavy_fn, ()) for i in range(num_procs)]
results = [res.get() for res in multiple_results]
for r in results:
print(r[0], r[1])
print(f"Done at {datetime.now()}")
print(f"Time taken = {time.perf_counter() - start}s")
結果如下:
num_processes total_time_taken
1 28.25
2 14.28
3 10.2
4 7.35
5 7.89
6 8.03
7 8.41
8 8.72
9 8.75
16 8.7
40 9.53
以下對我來說很有意義:
沒有意義的是:
htop
顯示所有 CPU 的利用率接近 100%。當並行運行 4 個時,其中只有 4 個處於 100%,這是有道理的。)問: “為什么一次並行運行 5 到 8 個比一次運行 4 個更糟糕?”
好吧,有幾個原因,我們將從一個靜態的、最容易觀察到的原因開始:
由於硅設計(他們為此使用了一些硬件技巧)沒有擴展到超過 4.
因此,最后一個阿姆達爾定律解釋並促進了僅+1
升級處理器數量的加速是 4 並且任何下一個 +1 都不會以在 { 2, 3, 4 }-case 中觀察到的相同方式提升性能:
此lstopo
CPU 拓撲圖有助於開始解碼WHY (此處為 4 核,但邏輯與您的 8 核芯片相同 - 在您的設備上運行lstopo
以查看更多體內細節):
┌───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┐
│ Machine (31876MB) │
│ │
│ ┌────────────────────────────────────────────────────────────┐ ┌───────────────────────────┐ │
│ │ Package P#0 │ ├┤╶─┬─────┼┤╶───────┤ PCI 10ae:1F44 │ │
│ │ │ │ │ │ │
│ │ ┌────────────────────────────────────────────────────────┐ │ │ │ ┌────────────┐ ┌───────┐ │ │
│ │ │ L3 (8192KB) │ │ │ │ │ renderD128 │ │ card0 │ │ │
│ │ └────────────────────────────────────────────────────────┘ │ │ │ └────────────┘ └───────┘ │ │
│ │ │ │ │ │ │
│ │ ┌──────────────────────────┐ ┌──────────────────────────┐ │ │ │ ┌────────────┐ │ │
│ │ │ L2 (2048KB) │ │ L2 (2048KB) │ │ │ │ │ controlD64 │ │ │
│ │ └──────────────────────────┘ └──────────────────────────┘ │ │ │ └────────────┘ │ │
│ │ │ │ └───────────────────────────┘ │
│ │ ┌──────────────────────────┐ ┌──────────────────────────┐ │ │ │
│ │ │ L1i (64KB) │ │ L1i (64KB) │ │ │ ┌───────────────┐ │
│ │ └──────────────────────────┘ └──────────────────────────┘ │ ├─────┼┤╶───────┤ PCI 10bc:8268 │ │
│ │ │ │ │ │ │
│ │ ┌────────────┐┌────────────┐ ┌────────────┐┌────────────┐ │ │ │ ┌────────┐ │ │
│ │ │ L1d (16KB) ││ L1d (16KB) │ │ L1d (16KB) ││ L1d (16KB) │ │ │ │ │ enp2s0 │ │ │
│ │ └────────────┘└────────────┘ └────────────┘└────────────┘ │ │ │ └────────┘ │ │
│ │ │ │ └───────────────┘ │
│ │ ┌────────────┐┌────────────┐ ┌────────────┐┌────────────┐ │ │ │
│ │ │ Core P#0 ││ Core P#1 │ │ Core P#2 ││ Core P#3 │ │ │ ┌──────────────────┐ │
│ │ │ ││ │ │ ││ │ │ ├─────┤ PCI 1002:4790 │ │
│ │ │ ┌────────┐ ││ ┌────────┐ │ │ ┌────────┐ ││ ┌────────┐ │ │ │ │ │ │
│ │ │ │ PU P#0 │ ││ │ PU P#1 │ │ │ │ PU P#2 │ ││ │ PU P#3 │ │ │ │ │ ┌─────┐ ┌─────┐ │ │
│ │ │ └────────┘ ││ └────────┘ │ │ └────────┘ ││ └────────┘ │ │ │ │ │ sr0 │ │ sda │ │ │
│ │ └────────────┘└────────────┘ └────────────┘└────────────┘ │ │ │ └─────┘ └─────┘ │ │
│ └────────────────────────────────────────────────────────────┘ │ └──────────────────┘ │
│ │ │
│ │ ┌───────────────┐ │
│ └─────┤ PCI 1002:479c │ │
│ └───────────────┘ │
└───────────────────────────────────────────────────────────────────────────────────────────────────────────────────┘
仔細觀察,比如調用hwloc
-tool: lstopo-no-graphics -.ascii
,顯示了相互處理獨立性在哪里結束- 這里是共享L1
指令緩存的級別( L3
也是共享的,但是在層次結構的頂部,並且規模如此之大,僅困擾大型問題解決者,而不是我們的情況)
問: “為什么並行運行 8 的速度沒有並行運行 4 的兩倍,即為什么不是
~3.5s
?”
因為熱管理。
加載到 CPU 內核上的工作越多,通過硅迷宮驅動~3.5+ GHz
的電子產生的熱量就越多。 熱限制是那些阻止 CPU 計算能力進一步提高性能的限制,僅僅是因為我們所知道的物理定律不允許超出某些材料定義的限制。
那么接下來會發生什么?
CPU 設計沒有繞過物理(那是不可能的),而是我們,用戶 - 通過向我們承諾一個具有~3.5+ GHz
的 CPU 芯片(但實際上,CPU 只能將這個時鍾頻率用於少量時間 - 直到散發的熱量沒有使硅接近熱限制 - 然后,CPU 將決定降低自己的時鍾速率作為過熱防御步驟(這會降低性能,不是嗎?)或者一些 CPU 微架構可能會跳躍(移動處理流程)到另一個免費的、因此更酷的 CPU 內核(它承諾在那里提供更高的時鍾速率(至少在一小段時間內)但也降低了性能,因為躍點不會在零時間發生並且不會以零成本發生(緩存丟失,重新獲取等)
這張圖片顯示了核心跳躍情況的快照 - 核心0-19
過熱並且處於熱節流上限之下,而核心20-39
可以(至少目前)全速運行:
兩種熱約束(將 CPU 潛水到液氮池中已為“流行”雜志展示,但對於任何可持續計算來說都不是一個合理的選擇,因為從深度冷凍狀態到6+ GHz
的機械應力時鍾頻率的蒸汽形成過熱器會破壞 CPU 的主體,並會導致 CPU 因裂縫和機械疲勞而死亡,但在少數工作負載中 - 所以這是一個禁區,因為任何嚴肅項目的ROI 都是負的) .
基於體內預測試的員工池的良好冷卻和合適的規模是這里唯一確定的賭注。
其他架構:
最可能的原因是您在使用同時多線程 (SMT)的 CPU 上運行程序,在 Intel 單元上更廣為人知的是超線程。 在 wiki 之后引用,對於物理上存在的每個處理器內核,操作系統會尋址兩個虛擬(邏輯)內核並在可能的情況下在它們之間共享工作負載。 這就是這里發生的事情。
您的操作系統說 8 個內核,但實際上它是 4 個帶 SMT 的內核。 該任務顯然受 CPU 限制,因此任何超出物理內核數量的增加都不會帶來任何好處,只會帶來多處理的開銷成本。 這就是為什么您會看到性能幾乎呈線性增長,直到達到(物理!)最大值。 核心數量 (4),然后在需要為這個 CPU 密集型任務共享核心時減少。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.