Featured image of post 【Python 平行運算 #4】python thread multiprocess 比較總整理

【Python 平行運算 #4】python thread multiprocess 比較總整理

前言

在 python 中有 thread 與 multiprocess 兩種平行處理程式的方式,
兩者分別的特性為:

  • thread: 可直接使用全域變數 (global) 交換資訊
  • multiprocess: 需透過設定特定通道 (多核心執行的中央變數管理,另一篇文會提到) 才能拿到資訊

也因此會有不同的特性:

  • thread: 適合小任務、資訊共用的任務 (直接拿 global 資訊來用)
  • multiprocess: 適合大任務、資訊獨立的任務 (把相關資訊交由其他核心處理後,不太需要拿取新資訊)

而在時間上,python 的 thread 實作有使用 GIL (global interpreter lock) ,
這是為了保護程式取用資料衝突的機制 (一般而言,我們會自己建立 mutex 或 lock 來實現這一點),
但也因為內建此機制的原因,實際執行上會慢於 multiprocess。

(可以有一種想法是,當 python 的 thread 實現方式是建立在大量的 context switch上)

而 multiprocess 可以幫助我們更好的運用硬體的多核心資源,
也就是將電腦的能力發揮到更極限,達到更好的效果。
(一般執行程式只需要一個核心)

但要注意:送資料到別的核心需要時間
如果是簡單不需要太多時間的任務,
使用多核心運算的方式反而會在資料搬運上浪費更多時間。

小整理

功能threadmultiprocess
速度快 (受限於 GIL)更快
電腦資源使用極限更極限
資訊共用容易度相對容易複雜 (注意:送資料到別的核心需要時間)
適合任務小任務、資訊共用的任務大任務、資訊獨立的任務

thread 與 multiprocess 比較

threading 重點摘要

threading 是透過 context-switch 的方式實現
也就是說,我們是透過 CPU 的不斷切換 (context-switch),實現平行的功能。
當大量使用 threading 執行平行的功能時,反而會因為大量的 context-switch,
實現了程式平行的功能,但也因為大量的 context-switch ,使得程式執行速度更慢」。

multiprocessing 重點摘要

multiprocessing 在資料傳遞上,會因為需要將資料轉移至其他 CPU 上進行運算,
因此會需要考慮資料搬運的時間,
而多核心真正的實現「平行運算的功能」,當任務較為複雜時,效率一定比較好。

thread 與 multiprocess 比較圖

從下圖我們可以看到任務被完成的「概念」時間

  • main 1~4, main-end
  • 任務 A1, A2
  • 任務 B1, B2
  • 任務 C1, C2

請留意圖中粗線的部分:

  • 在 multithread 中,
    CPU context-switch 會額外消耗我們程式執行的時間,程式實際完成時間可能比一般的還要慢。
  • 在 multiprocess 中, 我們需要將資料轉移至其他 CPU 會額外消耗我們程式執行的時間,如果任務過於簡單,效益可能不大。
  • 雖然示意圖中明顯感覺較快,但前提是任務夠複雜
    也就是說,「任務難度執行的時間 > 資料轉移至其他 CPU 的時間效益」,不然只會更慢。