2

各入力値が,(たとえば500MB)の大文字小文字の入力値が一般的に同じ場合、multiprocessing.Pool.map()と並行して多くの結果を計算するのが効率的ですか? multiprocessingの仕組みは、各入力値のpickled版をプール内の各ワーカープロセスに送信することによると思います。最適化が行われない場合は、入力値ごとに多くのデータをmap()に送信することを意味します。これは本当ですか?私はすぐにmultiprocessingコードを見ましたが、何も明らかではありませんでした。より一般的にいつPythonでmultiprocessing.Poolでmap()を使用しないのですか?大入力値の場合

、シンプルなものを並列化戦略をあなたがそれらの各ベクトルは常に異なっているタプル(vector, very_large_matrix)、あること、言っ万個の値にmap()を行うようお勧めしますが、唯一の5種類が非常に大きな存在と言っているところ行列?

PS:大きな入力が実際に「徐々に」が表示される行列:2,000ベクトルが最初最初行列と一緒に送られ、その後、2000のベクトルが第2のマトリックスで送信され、など

+0

私は[Pythonマルチプロセッシング:プロセス間で大規模な読み取り専用オブジェクトを共有すると思いますか?](http://stackoverflow.com/q/659865/1132524)では、探している回答があるかもしれません。 –

+0

入力いただきありがとうございます。あなたが参照する質問とこれとの違いは、大きな行列は本質的にマップの入力値*であることです(リンクされる質問は単一の大きなオブジェクトを使用するだけです)。さらに、上の回答の中のいずれの解決策もこの質問の場合に適合しているようには見えません。 – EOL

答えて

1

私はと思います明らかな解決策は、オブジェクト自体の複製ではなく、very_large_matrixへの参照を送信することです。 5つの大きな行列がある場合は、それらをメインプロセスで作成します。次にmultiprocessing.Poolがインスタンス化されると、親プロセスのアドレス空間をクローン化するいくつかの子プロセスが作成されます。つまり、プール内に6つのプロセスがある場合、(1 + 6)* 5の異なる行列が同時にメモリに格納されます。

だから、メインプロセス内のすべてのユニーク行列の参照を作成します。

matrix_lookup = {1 : matrix(...), 2 : matrix(...), ...} 

を次にワーカープロセスへのベクトルと一緒にmatrix_lookupで各行列のインデックスを渡します

p = Pool(6) 
pool.map(func, [(vector, 1), (vector, 2), (vector, 1), ...]) 
+0

これは良いアイデアのように思えます。私は1つの質問を持っています:書き込み*呪いの恐ろしい*コピーは最終的に各プロセスで各大行列のコピーを強制するのでしょうか?私は、Pythonのオブジェクト参照カウントがオブジェクトと共に格納されていることを読んでいます。オブジェクト参照を使って参照カウントを増やすと、オブジェクト全体がフォークされたプロセスにコピーされます(ほとんどのオペレーティングシステムでWindowsが正しく理解されれば悪化します)。 – EOL

+0

はい、恐ろしい書き込みのコピーはそれを行います。しかし、メモリ内に5 *(P + 1)の行列(ここでPはプール内のプロセスの数)を持つことは、map()に渡されるリスト内の各項目の1つの行列よりも大幅に少なくなります。 –

+0

コピーオンライトについてのお礼をありがとうございます。私は、リスト内の項目がmap()に渡された理由がメモリ内に5 *(P + 1)の行列を持つよりも "かなり多くの"メモリを使用する理由を理解していません。実際、リストのメモリフットプリントは、本質的に5 *(*)マトリックスのサイズよりも小さい* 5マトリックス*のサイズです(理由はPythonが内部的に5つのマトリックスへのポインタを使用するためです)。 – EOL

1

同様の問題、大きなデータセットの計算を並列化してみました。あなたが言及したようにmultiprocessing.Pool.mapは、引数を漬けます。私がやったのは、自分自身のfork()ラッパーを実装して、戻り値を親プロセスに戻すだけだったので、引数を消してしまうのを避けました。また、ラッパーの上に並列map()があります。

+0

すべてのプロセスで大きなデータセットが複製されましたか?私が正しく理解していれば、あなたは*大きなデータセットを持っていました。質問は、いくつかの大きなセットを持つことに関するものです(http://stackoverflow.com/q/659865/1132524-で単一の大きなデータセットに対して既に解決策があります)あなたも追加したい)。 – EOL

+1

PS:ここでは、読み取り専用オブジェクトのこの「コピーオンライト」メモリ複製への参照があります:http://stackoverflow.com/a/660026/42973。 – EOL

+0

これは、 'fork'された子でページをコピーする原因となる、Python参照カウントについての良い点です。 –