0

私は大きなnumpyアレイを状態に格納しているクラスを持っています。これにより、multiprocessing.Poolが極端に遅くなります。このコードは(とない)で約2秒で実行する必要があることを意味し、私はCPUに4つのコアを持っている状態で大きな配列を持つマルチプロセッシング

from multiprocessing import Pool 
import numpy 
import time 
from tqdm import tqdm 

class MP(object): 
    def __init__(self, mat): 
     self.mat = mat 

    def foo(self, x): 
     time.sleep(1) 
     return x*x + self.mat.shape[0] 

    def bar(self, arr): 
     results = [] 
     with Pool() as p: 
      for x in tqdm(p.imap(self.foo, arr)): 
       results.append(x) 
     return results 

if __name__ == '__main__': 
    x = numpy.arange(8) 
    mat = numpy.random.random((1,1)) 
    h = MP(mat) 
    res = h.bar(x) 
    print(res) 

:ここではMREのです。 (tqdmは進行状況バーとして2秒を示していますが、この例では実際には必要ありません)。しかし、メインプログラムでは、私がmat = numpy.random.random((10000,10000))を実行すると、それは永遠に実行されます。私はこれがPoolがそれぞれの労働者のためにmatのコピーを作っているからだと思うが、matがクラスの状態にあり、コールに直接関与していないので、この仕組みがわからない。だから、私の質問は次のとおりです。

  1. この現象はなぜ起こりますか? (つまり、クラス内でPoolがどのように動作するのですか?何が正確に行われるのですか?どのようなコピーが作成され、何が参照によって渡されますか)。
  2. この問題にはどのような回避策がありますか?

編集:私の本当の問題のより代表的である、matを利用するためにfooを修正。

+0

あなたのメインプログラムの 'x'の大きさは? –

+1

あなたのメインプログラムでは、 'p.imap'に渡す関数は' MP'のメソッドである必要がありますか、それともアンバウンド関数なのでしょうか? –

+0

@JeremyMcGibbon良い点。私の例は私の本当の問題の良い表現ではなかったと思う。関数は実際に 'mat'から読み込むので、関数は' MP'のメソッドである必要があります。 – ved

答えて

0

あなたはmatが直接imapコールに関与していないと言うと、私はMPの状態は(それがある場合、下記のコメントと私はこの回答を削除します)imap呼び出しで使用されていない一般的に推測している場合。その場合は、MPの代わりに、アンバインド関数としてfooと記述する必要があります。 fooの各実行がselfに渡される必要があるため、今度はmatがコピーされている理由は、self.matを含んでいます。

すぐにかかわらず、マットのサイズの

次が実行する:それは実際にmatから読み取る必要がないので、実際にMPを渡す必要がない

from multiprocessing import Pool 
import numpy 
import time 
from tqdm import tqdm 


class MP(object): 

    def __init__(self, mat): 
     self.mat = mat 

    def bar(self, arr): 
     results = [] 
     with Pool() as p: 
      for x in tqdm(p.imap(foo, arr)): 
       results.append(x) 
     return results 

def foo(x): 
    time.sleep(1) 
    return x * x 

if __name__ == '__main__': 
    x = numpy.arange(8) 
    mat = numpy.random.random((10000, 10000)) 
    h = MP(mat) 
    res = h.bar(x) 
    print(res) 

foo場合は、matを送信しないようにする方法はありませんあなたの質問2は「あなたができない」以外の答えを持っていません。しかし、うまくいけば私はあなたの質問に答えました。

関連する問題