Linux 上のタスクセットを使用したマルチコア システムでの Python グローバル インタープリター ロック (GIL) の回避策は?

StackOverflow https://stackoverflow.com/questions/990102

質問

Python Global Interpreter Lock (GIL) に関するこの講演を見終えたところです http://blip.tv/file/2232410.

その要点は、GIL はシングルコア システムにとって非常に優れた設計であるということです (Python は基本的にスレッドの処理/スケジューリングをオペレーティング システムに任せます)。しかし、これはマルチコア システムでは重大な裏目に出る可能性があり、最終的に IO 集中型のスレッドが CPU 集中型のスレッドによって大幅にブロックされ、コンテキスト切り替えの費用、ctrl-C の問題[*] などが発生します。

したがって、GIL では基本的に Python プログラムを 1 つの CPU で実行するように制限されているため、これを受け入れて、単に Linux でタスクセットを使用して、プログラムのアフィニティをシステム上の特定のコア/CPU に設定してはどうでしょうか (特に次のような状況では) と考えています。マルチコア システム上で実行される複数の Python アプリ)?

したがって、最終的に私の質問は次のとおりです。Linux で Python アプリケーションを使用してタスクセットを使用した人はいますか (特に、特定のコアにバインドされた 1 つまたは 2 つの Python アプリケーションで複数のコアを使用できるように、Linux システムで複数のアプリケーションを実行する場合)、試した場合、結果はどうなりましたか?やる価値はあるのか?特定のワークロードでは状況が悪化しますか?私はこれを実行してテストするつもりです (基本的にプログラムの実行に時間がかかるかどうかを確認します) が、他の人からあなたの経験について聞きたいと思っています。

追加:David Beazley (リンクされたビデオで講演している人) は、一部の C/C++ 拡張機能は GIL ロックを手動で解放し、これらの拡張機能がマルチコア用に最適化されているかどうか (つまり、科学データや数値データの分析など) の場合、数値計算処理においてマルチコアの利点が得られるのではなく、拡張機能が単一のコアに限定されるため事実上機能不全に陥ります (したがって、プログラムの速度が大幅に低下する可能性があります)。一方、このような拡張機能を使用していない場合は、

マルチプロセッシング モジュールを使用しない理由は、(この場合) プログラムの一部がネットワーク I/O バウンド (HTTP リクエスト) に大きく依存しているためです。そのため、ワーカー スレッドのプールを持つことは、すぐにパフォーマンスを引き出す優れた方法であるためです。スレッドが HTTP リクエストを発行し、I/O を待機しているため GIL を放棄し、別のスレッドがその処理を実行できるため、プログラムの一部は CPU に大きなダメージを与えることなく 100 以上のスレッドを簡単に実行でき、実際に使用できるようになります。利用可能なネットワーク帯域幅。スタックレス Python などに関しては、プログラムを書き直したり、Python スタックを置き換えたりすることにはあまり興味がありません (可用性も懸念されます)。

[*] メインスレッドのみがシグナルを受信できるため、ctrl-C を送信すると、Python インタープリターは基本的にシグナルを処理できるようにメインスレッドを実行させようとしますが、どのスレッドが実行されるかを直接制御しないため (これはオペレーティング システムに任されています) 基本的に、最終的にメイン スレッドに到達するまでスレッドを切り替え続けるように OS に指示します (運が悪いとしばらく時間がかかる場合があります)。

役に立ちましたか?

解決

私は、Pythonでのパフォーマンスの向上のためのタスクセットを使用して、誰のことを聞いたことがありません。他の人があなたのベンチマーク手法を批判し、検証を提供することができますので、それはあなたのケースで発生し、間違いなくあなたの結果を公開することはできませんという意味ではありません。

個人的に、しかし、私は、メッセージキューを使用してCPUバウンドのスレッドから、あなたのI / Oスレッドを切り離すでしょう。そうすれば、あなたのフロントエンドは現在、完全にI / O(HTTPインターフェースを持ついくつかの、メッセージ・キュー・インターフェースを持ついくつかの)バウンドし、あなたのスレッド状況のための理想的なネットワークです。そして、CPU強烈なプロセスは、マルチプロセッシングを使用するか、単にメッセージ・キューに到着する作業を待っている個々のプロセスのいずれかとすることができる。

長期的には、あなたはまた、ツイストや<のhref =「http://wiki.secondlife.com/wiki/Eventlet」のrel =」のようないくつかのものを使用して、ネジI / Oフロントエンドを置き換えることを検討することをお勧めします彼らは、スケーラビリティを向上させる必要があり、パフォーマンスを助けにはなりません場合でも、のでnoreferrer "> eventlets を。あなたは、任意の数のマシン、必要に応じて+のCPUの上にメッセージキューを実行することができますので、あなたのバックエンドは、今すでにスケーラブルです。

他のヒント

別の解決策は、次のとおりです。 http://docs.python.org/library/multiprocessing.htmlする

注1:これはのないPython言語の制限が、CPythonの実装の

注2:親和性に関しては、お使いのOS自体ことをやって問題を持つべきではありません。

興味深い解決策は、Ryan Kelly がブログで報告した実験です。 http://www.rfk.id.au/blog/entry/a-gil-adventure-threading2/

結果は非常に満足のいくものであるようです。

私は長年にわたって十分な親指の次のルールを見つけた:労働者がいくつかの共有状態に依存している場合は、私はコアごとに1つのマルチプロセッシング・プロセスを使用します(CPUが割り当てられている)、およびコアあたりのワーカースレッドの修正プール(I / Oバウンド)。 OSは、コアに異なるPythonのプロセスをassiginingの世話をします。

PythonのGILは、Pythonインタプリタごとです。すなわち、マルチプロセッシングを行うことは、単に複数のインタプリタを起動(即ち並行処理のために別々のプロセスの代わりにスレッドを使用して)、次いで、(例えば、ソケットなどの)プロセス間通信のためのいくつかの他のIPCプリミティブを使用している間、それに伴う問題を回避する唯一の手段。それは言われて、GILは、I / O呼び出しをブロックすると、スレッドを使用して問題はありません。

前述したようにGILの主な問題は、同時に2つの異なるPythonコードのスレッドを実行することができないということです。ブロッキングI / O呼び出しでブロッキングスレッドがブロックされ、従って、Pythonコードをexecutinされていません。これは、GILをブロックしていないことを意味します。あなたが別々のpythonのスレッドで2つのCPU集中型のタスクを持っている場合はGILはPythonでマルチプロセッシングを殺すところ(以前指摘したように、唯一のCPythonの実装)、それはです。 GILは、CPU#0は、他のPythonのスレッドを実行ビジーであるPythonのスレッドを実行からCPU#1を停止させるためである。

GILような時間はPythonから除去されるまで、

、コルーチンは、スレッドの代わりに使用することができます。私は、この戦略は、少なくとも一つのケースでgreenletsを使用して、2つの成功したベンチャー企業で実施されていることを良い権限にそれを持っています。

この記事は、結果リストに常にある私私の考えを共有していない前に、私はこの過去のことはできないだろうこれはかなり古い質問ですが、毎回ので、私は、マルチコアシステム上のPythonとパフォーマンスに関連する情報について検索します。

あなたはタスクごとにスレッドを作成するのではなくマルチプロセッシングモジュールを使用することができ、それはあなたのコードの解釈はCPythonのcompierの別のプロセスを作成します。 それはあなたのアプリケーションは、マルチコアシステムを利用することになるだろう。 私はこのアプローチに見る唯一の問題は、あなたがメモリに全体の新しいプロセス・スタックを作成することによって、かなりのオーバーヘッドを持っているということです。 ( http://en.wikipedia.org/wiki/Thread_(computing)#How_threads_differ_from_processes の)

Pythonのマルチプロセッシングモジュール: http://docs.python.org/dev/library/multiprocessing.htmlする

私はマルチプロセッシングモジュールを使用していない

"の理由は、プログラムの(この場合)の部分が大きく、ネットワークI / Oバウンド(HTTPリクエスト)がそうワーカースレッドのプールを有するための素晴らしい方法ですされていることです箱から出してパフォーマンスを絞る... "

これについて、私はあなたがあまりにもプロセスのプールを持つことができることを推測:<のhref = "http://docs.python.org/dev/library/multiprocessing.html#using-a-pool-of-労働者」のrel = "nofollowを"> http://docs.python.org/dev/library/multiprocessing.html#using-a-pool-of-workers の

肥満児、 レオ

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top