[解決済み] マルチプロセッシングにおける共有メモリ・オブジェクト
質問
メモリ上に大きなnumpy配列があり、その中に関数
func
があり、この巨大な配列を(他のいくつかのパラメータと一緒に)入力として受け取ります。
func
は異なるパラメータで並列に実行することができる。例えば
def func(arr, param):
# do stuff to arr, param
# build array arr
pool = Pool(processes = 6)
results = [pool.apply_async(func, [arr, param]) for param in all_params]
output = [res.get() for res in results]
マルチプロセッシングライブラリを使用すると、巨大な配列は異なるプロセスに複数回コピーされます。
異なるプロセスで同じ配列を共有する方法はありますか?この配列オブジェクトは読み取り専用で、決して変更されることはありません。
もっと複雑なのは、arrが配列ではなく、任意のpythonオブジェクトである場合、それを共有する方法はありますか?
[編集済み]です。
回答を読ませていただきましたが、まだ少し混乱しています。fork()はcopy-on-writeなので、pythonマルチプロセッシングライブラリで新しいプロセスを生成するときに追加のコストを呼び出さないはずです。しかし、次のコードは、巨大なオーバーヘッドがあることを示唆しています。
from multiprocessing import Pool, Manager
import numpy as np;
import time
def f(arr):
return len(arr)
t = time.time()
arr = np.arange(10000000)
print "construct array = ", time.time() - t;
pool = Pool(processes = 6)
t = time.time()
res = pool.apply_async(f, [arr,])
res.get()
print "multiprocessing overhead = ", time.time() - t;
を出力します(ちなみに、配列のサイズが大きくなるとコストが増えるので、やはりメモリコピーに関連するオーバーヘッドがあると思われます)。
construct array = 0.0178790092468
multiprocessing overhead = 0.252444982529
配列をコピーしていないのに、なぜこのような巨大なオーバーヘッドがあるのでしょうか?また、共有メモリはどの部分を節約してくれるのでしょうか?
どのように解決するのですか?
コピーオンライトを使用するオペレーティングシステムを使用している場合
fork()
セマンティクスを使用するオペレーティング システム (一般的な Unix など) を使用している場合、データ構造を決して変更しない限り、追加のメモリを占有することなくすべての子プロセスで利用できます。 特別なことをする必要はありません (オブジェクトを変更しないことを絶対に確認すること以外は)。
最も効率的なのは
あなた
を行うことができます。
は、配列を効率的な配列構造にパックすることでしょう (
numpy
または
array
で囲みます)、それを共有メモリに配置し、それを
multiprocessing.Array
でラップし、それを関数に渡します。
この回答は、その方法を示しています
.
もしあなたが
書き込み可能
共有オブジェクトが必要な場合は、何らかの同期やロックで包む必要があります。
multiprocessing
は
これを行うための2つの方法
: 共有メモリ (単純な値、配列、ctypes に適しています) を使用する方法、または
Manager
プロキシでは、1 つのプロセスがメモリを保持し、マネージャが他のプロセスから (ネットワーク上でも) そのメモリへのアクセスを調停します。
は
Manager
アプローチは任意の Python オブジェクトで使用できますが、オブジェクトをシリアライズ/デシリアライズしてプロセス間で送信する必要があるため、共有メモリを使用した同等品よりも遅くなります。
には
Pythonで利用できる豊富な並列処理ライブラリやアプローチがあります。
.
multiprocessing
は優秀でよくまとまったライブラリですが、特別なニーズがある場合は、他のアプローチの方がよいかもしれません。
関連
-
Python関数の高度な応用を解説
-
python call matlab メソッドの詳細
-
Python カメの描画コマンドとその例
-
Python jiabaライブラリの使用方法について説明
-
[解決済み】pygame.error: ビデオシステムが初期化されていない
-
[解決済み】numpy: true_divide で無効な値に遭遇
-
[解決済み】TypeErrorを取得しました。エントリを持つ子テーブルの後に親テーブルを追加しようとすると、 __init__() missing 1 required positional argument: 'on_delete'
-
[解決済み】cアンダースコア式`c_`は、具体的に何をするのですか?
-
[解決済み] マルチプロセシングpool.mapを複数の引数で使用する方法
-
[解決済み] マルチプロセッシングにおける共有メモリ
最新
-
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の学習とデータマイニングのために知っておくべきターミナルコマンドのトップ10
-
Python interpreted model libraryによる機械学習モデル出力の可視化 Shap
-
Pythonの@decoratorsについてまとめてみました。
-
Pythonの画像ファイル処理用ライブラリ「Pillow」(グラフィックの詳細)
-
[解決済み】TypeError: unhashable type: 'numpy.ndarray'.
-
[解決済み] [Solved] sklearn error ValueError: 入力に NaN、infinity または dtype('float64') に対して大きすぎる値が含まれている。
-
[解決済み】Python: OverflowError: 数学の範囲エラー
-
[解決済み】Python - "ValueError: not enough values to unpack (expected 2, got 1)" の修正方法 [閉店].
-
[解決済み】 TypeError: += でサポートされていないオペランド型: 'int' および 'list' です。
-
[解決済み] マルチプロセッシングにおける共有メモリ