在python中要進行加速運算時,可能對於process 、thread、Concurrency、Parallelism等概念感到混淆,以及對於python提供加速運算的內建模組,諸如threading
、asyncio
、multiprocessing
、concurrent
感到疑惑,本文旨在幫助使用者建立基本觀念,幫助工具選擇
source: realpython.com/lessons/computers-latency/
現代電腦系統中,資料必須在不同的硬體層級進行運算與傳輸,但不同層級間的運算速度不等,而導致了延遲(latency)產生
延遲(latency)是指從發送請求到接收到相應的反應(response)所經過的時間。在電腦系統中,延遲可以出現在多個層面:
由於從CPU往外、經由Cashe、RAM(memory)、Disk、Network等層級的資料傳輸速度/延遲(Latency)呈現數量級的遞減,因此需要考量任務執行時,效能卡在哪個層級來選擇適合的對應處理方案
不同延遲原因的解決方案:
source: Shivprasad koirala。codeproject.com。Concurrency vs Parallelism
在python中,threading
和 asyncio
之間的最大區別是執行序(thread)/任務(task)輪流運行的方式
threading
模組
使用搶先式多任務處理(pre-emptive multitasking),操作系統可以搶佔thread以進行切換。操作系統實際上瞭解並掌控每個線程,並可以隨時中斷它以開始運行其他thread。
搶先式多任務處理非常方便,因為thread中的程式碼不需要執行任何操作即可進行切換。 由於存在“隨時”一詞,這也可能導致實作上的複雜與困難。因為切換可能發生在很小的單位,例如單個 Python 語法的中間,例如 x = x + 1
之類的簡單語法(涉及多步原子操作atomic operation,詳見深入 GIL)
asyncio
模組
使用協作式多任務處理(cooperative multitasking)。 這些任務必須通過明確宣告何時準備好退出來進行協作(程式碼必須稍作更改才能實現)
wiki
在電腦科學中,並行性(Concurrency)指的是一個程式、演算法或問題的不同部分或單元能夠以非順序或部分順序的方式執行,而不影響最終結果。這允許並行單元的平行執行,這在多處理器和多核心系統中可以顯著提高執行的整體速度。用更技術性的術語來說,並行性指的是一個程式、演算法或問題能夠分解為無序或部分有序的組件或計算單元。
同時執行多個任務的能力
這裡的同時是指物理上的同時,即同一時刻執行多個任務
並行關注的是提高執行效率
在python中使用multiprocessing
模組實現
通過multiprocessing
,Python 創建了新的process。 一個process可以視為幾乎完全不同的程式,儘管從技術上講,它們通常被定義為資源的集合,其中資源包括記憶體,文件(file handles )等。每個process都在自己的 Python 解釋器中運行
由於是不同的process,因此multiprocessing
程式中的每個程式碼邏輯都可以在不同的核心上執行,亦即"平行"
source : 2019。travishen。Generator as Coroutines
特點 | Cooperative Multitasking | Pre-emptive Multitasking |
---|---|---|
控制 | process控制CPU使用時間 | 作業系統控制CPU使用時間 |
中斷 | process自願釋放控制 | 作業系統可以在任何時間中斷進程 |
資源管理 | 依賴process合作和正確釋放資源、資源分配可能不夠公平或高效 | 作業系統積極管理和分配資源 |
響應性 | 可能受到單一process占用CPU的影響、一個不合作的process可能導致系統中斷 | 通常提供更好的系統響應性和用戶交互性 |
開發複雜性 | 相對簡單;process有更多的控制權、開發者需要確保process正確釋放CPU | 開發者不需要擔心process,但需要處理同步和並行問題 |
應用場景 | 適用於較簡單或事件驅動的系統 | 適用於需要高度交互和平行處理的系統 |
並行類型 (Concurrency Type) |
切換決定 | 處理器(Processors)數量 |
---|---|---|
搶占式多任務 Pre-emptive multitasking ( threading ) |
作業系統決定何時在Python外部切換任務 | 1 |
協作式多任務 Cooperative multitasking ( asyncio ) |
任務決定何時放棄控制(process自願釋放控制) | 1 |
多程序處理 Multiprocessing ( multiprocessing ) |
所有process在不同的處理器上同時運行 | Many |
modified from: realpython.com/python-concurrency
Cooperative Multitasking 是一種多任務處理策略,其中每個程序process自主管理其對CPU的使用。在這種模式下,一個process一旦開始執行,它將繼續運行,直到它主動選擇釋放CPU。這通常發生在process等待外部輸入/輸出(例如,讀取文件或網路通信)或者process自願給其他process使用CPU的時候
相對的,Pre-emptive Multitasking 是由作業系統控制的,它分配給每個process一個固定的執行時間(稱為時間片Time slice)。當一個process的時間片用完時,作業系統會中斷該進程,保存其當前狀態,並將CPU控制權轉移給下一個process。
並非所有演算法都能充分利用並行性
組件 | 功能 | 例子 | 挑戰 |
---|---|---|---|
生產者 Producer |
生產數據 | 接收來自客戶端的請求 並將其放入一個隊列中 |
確保數據的安全生產和傳遞, 避免競爭條件或數據不一致 |
工作者 Worker |
計算數據 | 從隊列中取出請求,處理它們 (例如查詢數據庫或執行計算) |
從生產者處有效地獲取數據,並可能需要與其他工作者協同工作 |
消費者 Consumer |
消耗數據 | 將工作者處理的結果 發送回客戶端 |
確保從工作者處安全且正確地獲取和使用數據,並可能需要處理來自多個工作者的數據 |
source: 2021。Jakob Jenkov。jenkov.com。The Producer Consumer Pattern
更多補充見[python - speed up] 多執行緒(multi-threading)的基本概念
threading
(I/O-Bound 類型任務適用)asyncio
(I/O-Bound 類型任務適用)multiprocessing
(CPU-Bound 類型任務適用)Concurrency總是帶來額外的複雜性,並且常常會導致難以發現的錯誤。
在遇到已知的性能問題之前,暫緩添加Concurrency,然後再確定需要哪種Concurrency
過早的優化是一切程式設計問題的根源 - Donald Knuth
Premature optimization is the root of all evil (or at least most of it) in programming. - Donald Knuth
決定優化程式後,下一步是確定瓶頸是CPU-bound的還是I/O-bound的
對於 I/O 綁定問題,Python 社區有一個普遍的經驗法則: “可以用asyncio
時就用 ,必要用threading
'時就用 ”。
asyncio
可以為這類程式提供最好的速度,但有時你需要一些關鍵 libraries ,但這些 libraries 可能還沒有被完整移植。
Python中提供concurrency(並行)功能的模組:
threading
(I/O-Bound 類型任務適用)asyncio
(I/O-Bound 類型任務適用)multiprocessing
(CPU-Bound 類型任務適用)concurrent
: 提供threading
與multiprocessing
的高階API封裝根據python Concurrent Execution官方文件提到:
multiprocessing — Process-based parallelism
concurrent.futures.ProcessPoolExecutor
提供了一個更高層級的介面用來將任務推送到背景程序(background process)而不會阻塞調用方程序(calling process)的執行。 與直接使用Pool介面相比,concurrent.futures API 能更好地允許將工作單元發往無需等待結果的下層進程池threading — Thread-based parallelism
concurrent.futures.ThreadPoolExecutor
提供了一個高層級介面用來向背景執行序(background thread)推送任務而不會阻塞調用方執行序(calling thread)的執行,同時仍然能夠在需要時獲取任務的結果。queue
提供了一個線程安全的介面用來在運行中的執行序(threads)之間交換數據。asyncio
提供了一個替代方式用來實現任務層級(task level)的並行而不要求使用多個操作系統的執行序(operating system threads)。Concurrency是獨立執行計算的組合,且並行性(concurrency)平行性(parallelism):
Concurrency
Parallelism
Concurrency is the composition of independently executing computations, and concurrency is not parallelism: concurrency is about dealing with lots of things at once but parallelism is about doing lots of things at once. Concurrency is about structure, parallelism is about execution, concurrency provides a way to structure a solution to solve a problem that may (but not necessarily) be parallelizable.
主題 | Concurrency | Parallelism |
---|---|---|
基本定義 | 在同一核心上使用重疊或時間分片執行多個任務。 | 在不同的核心上執行多個任務。 |
目標 | 在不過度使用資源的情況下感覺到平行處理。 | 為了性能實現實際的平行處理。 |
觀點 | 軟體設計:以合作的方式組成獨立執行的計算。 | 硬體:平行執行計算。 |
資源利用 | 輕 | 重 |
- Concurrency 指程式架構,將程式拆開成多個可獨立運作的工作,像是驅動程式都可獨立運作,但不需要平行化。
- Parallelism 則指程式執行,同時執行多個程式。
Concurrency 可能會用到 Parallelism,但不一定要用 Parallelism 才能實現 Concurrency。在 Concurrent 中,工作可拆分成「獨立執行」的部份,於是「可以」讓很多事情一起做,但「不一定」要真的同時做。但 Parallelism 著重規劃, 將能夠並行的程式,分配給不同硬體單元,使其同時執行。
comparison in concurrency and parallelism
velotio.com。Implementing Async Features in Python - A Step-by-step Guide
Fig:- A comparison in concurrency and parallelism