
シェア:
マックスはPythonデベロッパー・アドボケイトであり、通信API、機械学習、デベロッパー・エクスペリエンス、ダンスに興味を持つソフトウェア・エンジニアだ!物理学を専攻していたが、現在はオープンソースのプロジェクトに携わり、開発者の生活をより良くするためのものを作っている。
PythonのGILを削除する:それは起こっている!
所要時間:1 分
はじめに
PythonのGlobal Interpreter Lock (GIL)は、マルチコアプロセッサであっても、一度に1つのスレッドだけがPythonコードを実行できるようにするロック機構です。これはいくつかの利点がある一方で、Pythonで並列処理のために複数のCPUコアを利用するのは簡単ではないということを意味します。
最近、パイソン・ステアリング・カウンシルは、以下を承認する意向を示している。 PEP 703を承認する意向を示しました。これは、最も人気のあるPythonインタプリタであるCPythonからGILを取り除いたバージョンを作るという提案です。これは今後のPythonの開発に大きな影響を与えるので、何が起こっているのかを理解する価値があります。
この投稿では、なぜPythonにGILがあるのか、なぜGILを削除したいのか、そのために現在行われている作業について説明します。
なぜGILがあるのか?
GILはスレッド管理を簡素化し、Pythonの競合状態やメモリ破壊から保護し、開発者が安全に並行コードを書くことを容易にします。GILはPythonの初期にスレッドのサポートが追加されたときに導入されました。
互換性
多くのPythonパッケージ(とメインのPythonインタプリタであるCPython)は、本質的にスレッドセーフではないC拡張を多用しています。複数のスレッドが同じリソースにアクセスしようとする可能性があり、それは非常に悪い影響をもたらします。GILはC拡張の作成と使用をより安全にし、90年代の開発者がPythonを使ってソフトウェアを作り始めることを容易にし、普及を促進しました。
ガベージコレクションと参照カウント
もう1つの重要な理由は、Pythonがガベージコレクションをどのように扱うかに関係しています。ガベージコレクションとは、インタプリタが、プログラムの中で参照されなくなったり到達できなくなったりしたオブジェクトが占有するメモリを追跡し、回収する自動的なメモリ管理プロセスのことです。Pythonでは、ガベージコレクションには主に2つの方法がありますが、最も顕著なのは参照カウントと呼ばれる処理です。
Python における参照カウントは、メモリを管理する効率的な方法であり、リソースが使われなくなったときに解放されるようにすることで、Python プログラムのメモリリークを防ぐのに役立ちます。参照カウントは次のように動作します:
各オブジェクトは、そのオブジェクトを指している参照の数を記録している。
オブジェクトの参照カウントがゼロになるということは、そのオブジェクトへの参照がプログラム中にもうないことを意味する。
これは、そのオブジェクトが不要になったことを示す。
Pythonのメモリ管理システムは、オブジェクトが占有していたメモリを自動的に取り戻し、事実上削除します。
GILがなければ、同時に実行される複数のスレッドがオブジェクトの参照カウントを同時に操作し、競合状態やメモリ破壊につながる可能性がある。GILは安全装置として機能し、一度に1つのスレッドだけがPythonバイトコードを実行できるようにし、このような潜在的な問題を防ぎます。
なぜGILを撤去したいのか?
GILは、スレッドセーフをあまり気にせずにコードを書くことを簡単にする一方で、CPUバウンドタスクでマルチスレッドを使用することで期待できるパフォーマンス向上を制限する可能性もある。HTTPリクエストやファイル操作のようなI/Oバウンド・タスクでは、GILはそれほど影響しないので、そのような場合でもマルチスレッドの恩恵を受けることができる。ですから、Pythonでスレッドを使って多くのHTTPリクエストを送信するのであれば、パフォーマンスが向上する可能性がありますが、スレッドを使ってCPU負荷の高いタスクをたくさん実行するのであれば、おそらくそうならないでしょう。
もしGILが削除されれば、CPythonでは現在得られない、CPUに負荷のかかる作業をするときのスレッド化による性能上の利点を得ることができるでしょう。
並行性を改善する他のアプローチの何が問題なのか?
を使ったスレッディングと非同期処理は、どちらもパフォーマンスを向上させる方法だが、IOバウンド処理にしか使えない。 asyncioはどちらもパフォーマンスを向上させる方法だが、IOバウンド処理にしか使えない。しかし、CPUに束縛された処理に有効な方法がいくつかある。
Pythonは multiprocessingモジュールを使ってPythonライクなコードを書くこともできる。 Cythonを使ってPythonライクなコードを書くこともできる。どちらもCPUに依存する処理のパフォーマンスを向上させることができるが、デメリットもある。
マルチプロセシング
Pythonの multiprocessingモジュールを使うと、それぞれが独自のPythonインタプリタとメモリ空間を持つ別々のプロセスを作成することで、複数のCPUコアを使うことができます。これは、スレッド上で動作するGILをバイパスし、マシンの複数のコアを使用して真の並列実行を行うことができるため、CPUバウンドタスクに効果的です。
残念ながら、複数のプロセスを作成すると、スレッドに比べてリソースのオーバーヘッドが大きくなり、メモリ使用量と起動時間が増加します。また、プロセス間の通信はスレッド間よりも遅く、複雑です。最後に、プロセスはデフォルトではメモリを共有しないため、プロセス間でデータを共有し、同期させることがより難しくなります。
サイソン
CythonはPythonのスーパーセットで、Pythonライクなコードにパフォーマンス向上のためのアノテーションを追加して書くことができる。Python言語から完全に離れることなく、Pythonコードをより速く実行させる方法です。Cythonは、Python言語の使いやすさと読みやすさを保ちながら、重要な部分を最適化することで、コードをより速く実行できるようにします。
しかし、CythonはPythonよりも学習曲線が長く、C言語の構成要素の知識を必要とするため、アクセスしにくくなります。また、Cythonのコードを書いたり保守したりするのは、純粋なPythonのコードを書くよりも複雑でエラーが起こりやすく、特に元々Pythonで書かれたコードを書き直す場合はなおさらです。
つまり、パフォーマンスを向上させる方法はいくつかあるが、どちらも大きな欠点がある。このことは、PythonからGILを取り除くことに多くの関心が寄せられている理由を示している。
これまでの試みと成功しなかった理由
過去にいくつかのプロジェクトがCPythonからGILを削除しようと試み、いくつかの成功を収めている。 Gilectomyプロジェクトなどです。しかし、GILを取り除こうとする努力は、通常いくつかの欠点を伴います:
これは複雑な作業で、CPythonインタプリタにバグや不安定性をもたらす可能性があります。
それらは、既存のPythonコードやGILに依存しているライブラリを壊すかもしれません。
メモリ使用量が増える可能性がある。
既存のCベースのPython拡張機能は、大幅な変更が必要になるだろう。
しかし、主な欠点は、古いGILなしのプロジェクトでは、シングルスレッドのコードがGILを使った場合よりも遅くなるということです。つまり、CPUに負荷のかかる処理を高速化するためにマルチスレッドを使っていない場合、コードのパフォーマンスは通常のCPythonよりも悪くなります。
PEP 703パイソン運営評議会は を承認する予定です。はこのすべてを変えるものであり、広く支持されています。それについて話しましょう!
PEP 703って何?正しいGIL Pythonの使い方
PEP 703はPythonからGILを削除する方法を提案しますが、他のGILなしのPythonプロジェクトに影響を与えた非マルチスレッドコードへのパフォーマンスへの影響を避けることに成功しています。Python 運営評議会 は7月28日にPython Steering Council は7月28日にこの PEP を承認する意向を示し、no-GIL Python が主流になり、最終的には Python のデフォルトになる道を開きました。
どのように機能するのか?
シングルスレッド・コードの性能に影響を与えることなくGILを除去するための主な重要テクニックは、偏った参照カウントである。
偏った参照カウントでは、単一のスレッドによってアクセスされるオブジェクトは、複数のスレッドによってアクセスされるオブジェクトよりも効率的に参照カウントが管理されます。これは、シングルスレッド操作でこの技法を使ったno-GIL Pythonの性能は通常のPythonと同等である一方、マルチスレッドCPUバウンドPythonプログラムははるかに高速であることを意味します!
プロジェクトはまた、Pythonプログラムの中で変更される可能性のないトップレベルのモジュールオブジェクトの参照カウント処理を延期することで、no-GIL Pythonをより効率的にします。 Noneのようなオブジェクトは決して破棄されないのでカウントする必要はありません。Python オブジェクトのメモリ割り当て方法にも変更があり、スレッドセーフな方法でのメモリ割り当てがより簡単になりました。
素晴らしい!というわけで、問題はいつになったらノーGIL Pythonにアクセスできるようになるのか、ということになる。
ノーGIL Pythonの実装方法
Python運営評議会は、no-GIL PythonがCPythonのデフォルトバージョンになるための3つの段階について説明しています:
短期:Pythonのバージョン3.13(またはおそらく3.14)では、実験的なモードとしてno-GILビルドを導入する予定です。このモードは、使い方、APIの設計、パッケージング、配布についての洞察を得るために使われる予定です。
中期:GILなしビルドに対するコミュニティからの十分なサポートが確信できたら、それはサポートされるオプションになるだろうが、デフォルトではない。APIの互換性やコミュニティの準備状況などの要因によって時期は変わりますが、デフォルトにするための目標期日/バージョンが設定される予定です。彼らは、このフェーズには1~2年かかると見積もっているが、これより長くなる可能性もある。
長期:最終的なゴールは、後方互換性を破壊することなくGILを排除し、GILなしのビルドがデフォルトになることだ。彼らは、この段階に達するには今から5年かかると見積もっている。このプロセスの間、定期的な評価が行われ、後方互換性の闘争を回避しつつ、進捗が進んでいることが確認されるでしょう - Python 3を導入するための10年にわたる試練のような変化を誰も見たくはないでしょう...
結論
Pythonは大きな変化の瀬戸際にいる。(潜在的には)グローバルインタープリタロック(GIL)を削除することで、Pythonが複数のプロセッサコアを使用してパフォーマンスを向上させる能力を大幅に改善できる可能性がある。GILはセーフティネットの役割を担っていましたが、PythonがCPUに縛られたタスクで最新のプロセッサをフルに活用する可能性を妨げてきました。
過去の試みとは異なる PEP 703はスマートな解決策を提供し、偏った参照カウント、遅延参照カウント、不滅オブジェクトなどの技術を組み込んでいます。これは、シングルスレッドの Python プログラムが遅くならないようにする一方で、CPU の負荷が高いタスクに複数のスレッドを使うものを後押しします。
この変更は3つのステップで行われる。まず実験的なビルドモードで、次にサポートされるオプションとして、そして最後にデフォルト設定として、おそらく今後5年以内に行われる!この移行をスムーズにし、互換性の問題を回避し、Pythonによりパワーと効率をもたらすことが目的です。
この記事についてご質問がある場合は、お気軽に私たちの VonageコミュニティSlackにてご質問ください。 X(以前はTwitterと呼ばれていました)上でメッセージをお送りください。.
SMSの送信、音声通話、ビデオ会議、2ファクタ認証、詐欺防止など、通信に関するあらゆるAPIの使用に興味がある場合は、次のことが可能です。 無料のVonage開発者アカウント(無料クレジット付き!)にサインアップしてください。.