Pythonがグローバルインタプリタロックの解消へ、マルチスレッド処理の高速化実現
今回は「Pythonがグローバルインタプリタロックの解消へ、マルチスレッド処理の高速化実現」についてご紹介します。
関連ワード (不要、向上、方向性等) についても参考にしながら、ぜひ本記事について議論していってくださいね。
本記事は、Publickey様で掲載されている内容を参考にしておりますので、より詳しく内容を知りたい方は、ページ下の元記事リンクより参照ください。
Python Software Foundationのステアリングカウンシル(Steering Council)は、Pythonのグローバルインタプリタロック(Global Interpreter Lock)を解消する方向で開発を進めていくことを明らかにしました。
グローバルインタプリタロックとは?
グローバルインタプリタロックとは、その名前が示すとおりインタープリタ全体で1つのロックを持つことです。
これによりシングルスレッドのプログラムにおいては細かなロック制御が不要となって速度の向上がはかれる一方、マルチスレッドの平行性は制限されるという欠点があります。
また、スレッドセーフではないC言語などによるライブラリとの結合が容易となっています。
Pythonの標準実装であるCPythonでは、以前からグローバルインタプリタロックが採用されていました。
グローバルインタプリタロックを解消する提案
このグローバルインタプリタロックを採用してきたPythonの仕様と実装に対して、これを解消してPythonのオプションとするという提案が今年(2023年)1月に「PEP 703 – Making the Global Interpreter Lock Optional in CPython」として行われました。
PEP 703の概要は次のようなものです。
CPython’s global interpreter lock (“GIL”) prevents multiple threads from executing Python code at the same time. The GIL is an obstacle to using multi-core CPUs from Python efficiently. This PEP proposes adding a build configuration (–disable-gil) to CPython to let it run Python code without the global interpreter lock and with the necessary changes needed to make the interpreter thread-safe.
CPythonのグローバルインタプリタロック(”GIL”)は、複数のスレッドが同時にPythonコードを実行することを妨げています。GILはPythonでマルチコアCPUを効率的に使う上で障害となっているのです。このPEPでは、CPythonにビルド設定(-disable-gil)を追加して、Pythonコードをグローバルインタープリタロックなしで、インタプリタをスレッドセーフにするための必要な変更を加えて実行できるようにすることを提案します。
Pythonの方向性としてフリースレッド化へ
この提案を受けてステアリングカウンシルはコアデベロッパーらにアンケートを取りました。
1つ目の問いは、「コンセプトとしての、Pythonのフリースレッド化を積極的に検討すべきだと思いますか?」、2つ目の問いは「PEP 703を受け入れ、対応しメンテナンスしたいですか?」です。
つまり1つ目はPythonの進化の方向性としてグローバルインタプリタロックの解消がふさわしいかと問い、2つ目では確実に複雑かつ高度になるであろう実装をやる気があるかを問うものとなっています。
結果は以下のようになりました。
ここから読み取れるのは、Pythonのフリースレッド化は方向性として大いにポジティブだが、実装はやや面倒そうだ、というところでしょうか。
これはPython 4ではない。互換性を強く意識
これらの結果をもって、ステアリングカウンシルはPEP 703を受け入れ、Pythonのグローバルインタプリタロックを解消する方向性を明らかにしたわけです。
具体的には、ステアリングカウンシルは以下のような方針で、現在のPython 3との互換性を強く重視しつつ、グローバルインタプリタロックを解消していく作業を進めたいと説明しています。少し長いのですが、示された内容を引用します。
Long-term (probably 5+ years), the no-GIL build should be the only build. We do not want to create a permanent split between with-GIL and no-GIL builds (and extension modules).
長期的(おそらく5年以上)には、no-GILビルドが唯一のビルドであるべきです。私たちはwith-GILビルドとno-GILビルド(と拡張モジュール)の間に恒久的な分裂を作りたくありません。
We want to be very careful with backward compatibility. We do not want another Python 3 situation, so any changes in third-party code needed to accommodate no-GIL builds should just work in with-GIL builds (although backward compatibility with older Python versions will still need to be addressed). This is not Python 4. We are still considering the requirements we want to place on ABI compatibility and other details for the two builds and the effect on backward compatibility.
後方互換性には細心の注意を払いたいと思います。Python 3のときのような事態は起こしたくないため、no-GILビルドに対応するためにサードパーティが変更したコードは、with-GILビルドでも動作するようにすべきです(古いバージョンのPythonとの後方互換性にはまだ対処する必要がありますが)。これはPython 4ではありません。2つのビルドのABI互換性やその他の詳細、後方互換性への影響について、まだ検討中です。
Before we commit to switching entirely to the no-GIL build, we need to see community support for it. We can’t just flip the default and expect the community to figure out what work they need to do to support it. We, the core devs, need to gain experience with the new build mode and all it entails. We will probably need to figure out new C APIs and Python APIs as we sort out thread safety in existing code. We also need to bring along the rest of the Python community as we gain those insights and make sure the changes we want to make, and the changes we want them to make, are palatable.
no-GILビルドへの完全な切り替えにコミットする前に、コミュニティによるサポートを確認する必要があります。デフォルトの設定を変更するだけで、コミュニティがそれをサポートするために必要な作業をしてくれる、という期待はできません。私たちコアデベロッパーは、新しいビルドモードとそれに伴うさまざまな経験を積む必要があるのです。既存のコードに対してスレッドセーフであるような、新しいCのAPIやPython APIを見つけ出す必要もあるでしょう。また、そのような経験を得た上でも、私たちが行いたいとする今回の変更と、コミュニティが行ってもらいたいとする変更の両者が納得のいくものであることを確認するために、Pythonコミュニティ全体を巻き込む必要があります。
We want to be able to change our mind if it turns out, any time before we make no-GIL the default, that it’s just going to be too disruptive for too little gain. Such a decision could mean rolling back all of the work, so until we’re certain we want to make no-GIL the default, code specific to no-GIL should be somewhat identifiable.
私たちは、no-GILをデフォルトにする前に、その変更によって得るわずかな利益に対してあまりにも破壊的な変更が起こりうることが判明した場合、いつでもその決定を変えられるようにしたいと考えます。そのような決定は、それまでのすべての作業を元の木阿弥にすることを意味しかねないため、no-GILをデフォルトにしたいと確信するまでは、no-GILに特化したコードはある程度識別可能であるべきだと考えています。
今後はこれらを前提にしつつ、まずは実験的なビルドモードとしてPython 3.13でno-GILビルドを追加し、中期的にはno-GILビルドの本番利用を実行可能にする上で十分なコミュニティのサポートがあることを確信した後、長期的には上記で示された通り、no-GILなPython 3がデフォルトになるとしています。
ただし、ステアリングカウンシルはこの段階に達するまでに5年はかかると考えていることも明らかにしています。