Python 中有一把著名的鎖——全域性直譯器鎖(Global Interpreter Lock,簡寫 GIL),它的作用是防止多個本地執行緒同時執行 Python 位元組碼,這會導致 Python 無法實現真正的多執行緒執行。(注:本文中 Python 直譯器特指 CPython)
這把鎖在 Python 的早期發展中具有積極的作用(單核 CPU 時代),然而,它阻礙了 Python 在多核 CPU 上的並行程式設計,引起了開發者們與日俱增的詬病。
GIL 影響的主要是 CPU 密集型任務,比如科學計算與數值計算任務。
在最近釋出的 PEP-703 中,它概括了 GIL 對科學計算(主要是 AI/ML)造成的四類問題:
社群中想要移除 GIL 的呼聲以及嘗試,此起彼伏,綿綿不絕,但這個話題一直懸而未決。
抱怨、質疑、不滿、不甘、期盼等這些諸多的情緒,不是那麼容易平息的。然而,從一個積重已久的龐大的專案中移除一個根基性的設計,又談何容易?
2023 新年剛過,這個話題又一次熱了起來,又一輪對 GIL 的挑戰開始了。
這一次,事情似乎有了新的轉機,這次也許能成功了呢?
PEP-703 在今年 1 月 9 日新鮮出爐,雖然它目前仍是「草案」狀態未被採納,但是這份 PEP 的意義十分重大!
(注:每個 Python 學習者都應該基本瞭解 PEP,建議閱讀《學習Python,怎能不懂點PEP呢? 》)
這個 PEP 的作者是 Sam Gross,他是 nogil 專案的作者。Python貓的老讀者應該有印象,我們在 2021 年曾翻譯過他與 Python 核心開發者們的一次研討會的紀要,這份紀要裡概括了 nogil 的主要設計思路,同時回答了核心開發者們最為關注的約 20 個問題。
經過一年多時間的沉澱,nogil 專案現在終於形成了正式的 PEP,這意味著它被採納進 Python 主分支的可能性變大了一些啦!
PEP 的標題是《使 CPython 的 GIL 成為可選項》(Making the Global Interpreter Lock Optional in CPython),內容詳實,正文超過 1 萬字,這個體量的 PEP 絕對夠得上排在所有 PEP 的前十了。
簡單而言,這份提案提議給 CPython 增加一個構建時設定項--disable-gil
,作用是構建出一個執行緒安全的無 GIL 的直譯器。
為了實現無 GIL 的直譯器,Python 底層的部分設計必須作出變更,內容可以概括成四類:
如果這份 PEP 被採納實現的話,它會帶來一個不容忽視的問題:Python 將釋出兩個不同版本的直譯器,而第三方庫也要相應地開發/維護/釋出兩個版本的軟體包。
PEP-703 的作者也考慮到了這個問題,他提出的解決方案是與 Anaconda 一起釋出無 GIL 的 Python,同時在 conda 裡集中釋出管理那些相容了新 Python 的庫。
考慮到 Anaconda 在科學計算與數值計算領域的強大影響力,此舉既能較好地發揮 nogil Python 的用處,又能減少使用者及三方庫開發者面對兩種發行版時的割裂感。
值得注意的是,nogil 的 Python 還有一個更大的問題,那就是會影響單執行緒程式的效能。
基於 Python 3.11 版本,實現了有偏見的參照計數及永生物件後,Python 單執行緒效能會變慢 10%。
儘管這個數值在最新的 nogil 原型版本上可以降低到 5%,但是,另外至少還有兩項難以規避的效能下降點:
單執行緒的程式碼才是最廣泛的使用場景,可以說這會影響到每一個 Python 使用者。任何試圖移除 GIL 的專案都不可避免要面臨這項挑戰。
儘管存在著以上的兩大問題,但 PEP-703 還是很有可取之處的。
比如,相比於 2015 年提出的著名的 Gilectomy 專案(由 GIL ectomy 兩個單詞組合而成,ectomy 是一個醫學上的術語「切除術」),nogil 在單執行緒的效能上要快得多,同時可延伸性也更好。
比如,相比於 2021 年火熱的「夏農計劃」的作者 Eric Snow 提出的 PEP-684 方案(給每個子直譯器建立 GIL),後者一方面需要實現作為前提的多個 PEP(如 PEP-554、PEP-683),另一方面需要使用者處理多子直譯器間共用變數的麻煩。
在夏農計劃的《Python 3.12 目標》中,PEP-554 與 PEP-684 已經囊括在內了,版本目標是充分利用 Python 的子直譯器,讓子直譯器使用各自的 GIL,從而實現多執行緒的並行。
好訊息是,3.12 的計劃跟本文的主角 PEP-703 並不衝突。事實上,它們的很多設計細節是一致的,也就是說,這兩套對於 GIL 的改造方案是可以共存的,它們相互促進,事半功倍!
夏農計劃有 Python 之父 Guido van Rossum 站臺,還有財大氣粗的微軟支援著一支豪華的團隊投入開發(含 Guido 和 Eric Snow),因此,多直譯器多 GIL 的方案很可能會更快落地。
而 PEP-703 有 PSF 首位全職開發者 Łukasz Langa 的傾力支援,社群的反響也不錯,我覺得它今後落地的希望也挺大!
無論如何,這次夏農計劃和 PEP-703 掀起的對 GIL 的挑戰,比以往所有的嘗試都更猛烈,更有成功的可能,讓人不由得心生歡欣之喜~~
但願它們實現的一天不會太遠吧。
最後,感謝閱讀,如果你喜歡本文,請一定要點贊/分享支援哈~