27

それで、Python Global Interpreter Lock (GIL) http://blip.tv/file/2232410でこの講演を見終わったところです。

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

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

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

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

マルチプロセッシング モジュールを使用しない理由は、(この場合) プログラムの一部がネットワーク I/O バウンド (HTTP 要求) に大きく依存しているためです。スレッドが HTTP リクエストを開始し、I/O を待機しているため、GIL を放棄し、別のスレッドがそれを実行できるため、プログラムの一部は、CPU に大きな負担をかけずに 100 以上のスレッドを簡単に実行でき、実際に使用できるようになります。利用可能なネットワーク帯域幅。スタックレス Python/etc に関しては、プログラムを書き直したり、Python スタックを置き換えたりすることにあまり関心がありません (可用性も懸念事項です)。

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

4

7 に答える 7

10

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

注 1: これはPython 言語の制限ではなく、CPython 実装の制限です。

注 2: アフィニティに関しては、OS 自体で問題が発生することはありません。

于 2009-06-13T06:49:25.750 に答える
3

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

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

于 2011-11-20T20:51:04.953 に答える
1

GIL が Python から削除されるまでは、スレッドの代わりにコルーチンを使用できます。この戦略は、少なくとも 1 つのケースで greenlet を使用して成功した 2 つのスタートアップ企業によって実装されたという正当な権限があります。

于 2009-06-17T07:43:33.697 に答える
1

何年にもわたって、次の経験則で十分であることがわかりました。ワーカーが何らかの共有状態に依存している場合、コアごとに 1 つのマルチプロセッシング プロセス (CPU バウンド) を使用し、コアごとにワーカー スレッドの修正プール (I/O バウンド) を使用します。 )。OS は、さまざまな Python プロセスをコアに割り当てます。

于 2009-06-13T08:37:38.080 に答える
1

Python GIL は Python インタープリターごとです。つまり、マルチプロセッシング中に問題を回避するには、単純に複数のインタープリターを起動し (つまり、同時実行のためにスレッドではなく個別のプロセスを使用する)、プロセス間の通信に他の IPC プリミティブ (ソケットなど) を使用する必要があります。そうは言っても、I/O 呼び出しをブロックするスレッドを使用する場合、GIL は問題になりません。

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

于 2009-06-13T19:21:22.337 に答える
1

これはかなり古い質問ですが、マルチコア システムでの Python とパフォーマンスに関する情報を検索するたびに、この投稿が常に結果リストに表示されるため、この過去を私の考えを共有しないようにすることはできません。

マルチプロセッシング モジュールを使用すると、タスクごとにスレッドを作成するのではなく、コードを解釈する cpython コンパイラの別のプロセスを作成できます。アプリケーションがマルチコア システムを利用できるようになります。このアプローチで私が目にする唯一の問題は、メモリ上に新しいプロセス スタック全体を作成することで、かなりのオーバーヘッドが発生することです。( http://en.wikipedia.org/wiki/Thread_(computing)#How_threads_differ_from_processes )

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

「マルチプロセッシング モジュールを使用しない理由は、(この場合) プログラムの一部がネットワーク I/O バウンド (HTTP 要求) に大きく依存しているためです。そのため、ワーカー スレッドのプールを持つことは、箱から出してすぐにパフォーマンスを引き出すための優れた方法です。 ...」

これについては、プロセスのプールも持つことができると思います: http://docs.python.org/dev/library/multiprocessing.html#using-a-pool-of-workers

アット、レオ

于 2012-01-19T13:10:17.537 に答える