[解決済み] マルチプロセッシングにおける共有メモリ
質問
私は3つの大きなリストを持っています。最初のリストにはビット配列 (モジュール bitarray 0.8.0) が、残りの 2 つには整数の配列が含まれています。
l1=[bitarray 1, bitarray 2, ... ,bitarray n]
l2=[array 1, array 2, ... , array n]
l3=[array 1, array 2, ... , array n]
これらのデータ構造はかなりの量のRAMを消費します(合計16GB程度)。
を使って12個のサブプロセスを起動した場合。
multiprocessing.Process(target=someFunction, args=(l1,l2,l3))
これは、l1, l2, l3 がサブプロセスごとにコピーされるということでしょうか、それともサブプロセスでこれらのリストを共有するのでしょうか?あるいは、より直接的な言い方をすれば、16GBまたは192GBのRAMを使用するのでしょうか?
someFunction は、これらのリストからいくつかの値を読み取り、読み取った値に基づいていくつかの計算を実行します。その結果は親プロセスに返されます。リストl1、l2、l3はsomeFunctionによって変更されることはありません。
したがって、サブプロセスはこれらの巨大なリストを必要とせず、コピーもせず、代わりに親プロセスと共有すると仮定します。つまり、Linuxのコピーオンライト方式により、(いくつのサブプロセスを起動しても)プログラムは16GBのRAMを消費することになります。 私は正しいですか、それともリストがコピーされるような何かを見逃していますか?
EDIT : もう少し読み進めても、まだ混乱しています。一方ではLinuxはcopy-on-writeを使っていて、これはデータがコピーされないことを意味しているはずです。一方、オブジェクトにアクセスすると、その参照カウントが変更されます(なぜ、どういう意味なのか、まだよくわかりません)。それでも、オブジェクト全体がコピーされるのでしょうか?
例えば、someFunctionを次のように定義するとします。
def someFunction(list1, list2, list3):
i=random.randint(0,99999)
print list1[i], list2[i], list3[i]
この関数を使うと、各サブプロセスに対してl1、l2、l3が完全にコピーされることになるのでしょうか?
これを確認する方法はありますか?
EDIT2 もう少し読み進めて、サブプロセス実行中のシステムの総メモリ使用量を監視したところ、確かにサブプロセスごとにオブジェクト全体がコピーされているようです。そして、それは参照カウントのためであるようです。
l1、l2、l3 の参照カウントは、実は私のプログラムでは不要なのです。なぜなら、l1, l2, l3 は親プロセスが終了するまで(変更されずに)メモリ内に保持されるからです。それまで、これらのリストが使っていたメモリを解放する必要はありません。実際、プログラムが終了するまで、参照カウントは(これらのリストとその中のすべてのオブジェクトについて)0を超えたままであることは確実です。
そこで今度は、オブジェクトが各サブプロセスにコピーされないようにするには、どうすればよいかという問題になります。これらのリストとリスト内の各オブジェクトの参照カウントを無効にすることは可能でしょうか?
EDIT3
一応補足しておきます。サブプロセスでは
l1
,
l2
と
l3
またはこれらのリストに含まれるオブジェクト。サブプロセスでは、各サブプロセスでメモリをコピーすることなく、これらのオブジェクトの一部を参照できればよいのです。
解決方法は?
一般的に、同じデータを共有するには、2つの方法があります。
- マルチスレッド
- 共有メモリ
Pythonのマルチスレッドは(GILのため)CPUバウンドタスクに適していないので、その場合の通常の解決策は、次のようになります。
multiprocessing
. しかし、この解決策では、データを明示的に共有する必要があります。
multiprocessing.Value
と
multiprocessing.Array
.
通常、プロセス間でデータを共有することは、同期の問題があるため、最良の選択とは言えないかもしれないことに注意してください。以下も参照してください。 Pythonのドキュメント :
上記のように、同時並行プログラミングを行う場合、通常は 共有状態の使用はできるだけ避けた方がよいでしょう。これは 特に、複数のプロセスを使用する場合はそうです。
しかし、どうしても共有データを使用する必要がある場合は、以下のようになります。 マルチプロセシングは、そのためのいくつかの方法を提供します。
あなたの場合
l1
,
l2
と
l3
が理解できるような形で
multiprocessing
(を使用するなどして)。
multiprocessing.Array
) を作成し、それをパラメータとして渡します。
また、書き込みアクセスは必要ないとのことですが、その場合は
lock=False
さもないと、すべてのアクセスがシリアライズされたままになってしまいます。
関連
-
[解決済み】「RuntimeError: dictionary changed size during iteration」エラーを回避する方法とは?
-
[解決済み] 'int'オブジェクトに'__getitem__'属性がない。
-
[解決済み】IndexError: invalid index to scalar variableを修正する方法
-
[解決済み] マルチプロセシングpool.mapを複数の引数で使用する方法
-
[解決済み] Pythonでシングルトンを作成する
-
[解決済み] pandasを使った "大量データ "ワークフロー【終了しました
-
[解決済み] 組込み開関数におけるモードa、a+、w、w+、r+の違い?
-
[解決済み] 通常のPythonのリストと比較した場合、NumPyの利点は何ですか?
-
[解決済み] Pythonで明示的にメモリを解放するにはどうしたらいいですか?
-
[解決済み] マルチプロセッシングにおける共有メモリ・オブジェクト
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
pythonを使ったオフィス自動化コード例
-
Python 可視化 big_screen ライブラリ サンプル 詳細
-
Pythonの学習とデータマイニングのために知っておくべきターミナルコマンドのトップ10
-
Pythonコードの可読性を向上させるツール「pycodestyle」の使い方を詳しく解説します
-
パッケージングツールPyinstallerの使用と落とし穴の回避
-
[解決済み】お使いのCPUは、このTensorFlowバイナリが使用するようにコンパイルされていない命令をサポートしています。AVX AVX2
-
[解決済み】 AttributeError("'str' object has no attribute 'read'")
-
[解決済み】LogisticRegression: Pythonでsklearnを使用して、未知のラベルタイプ: '連続'を使用しています。
-
[解決済み】NameError: 名前 'self' が定義されていません。
-
[解決済み] マルチプロセッシングにおける共有メモリ・オブジェクト