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 사본을 만들고 있기 때문에 이것이 의심 스럽지만 matimap 호출에 직접적으로 관여하지 않았기 때문에 이것이 어떻게 작동하는지 잘 모르겠습니다. 따라서 내 질문은 다음과 같습니다.

  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에 전달되어야하기 때문에 이 지금 복사되는 이유는 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는 "귀하가 할 수 없습니다"이외의 답을 갖고 있지 않습니다. 하지만 잘하면 당신의 질문에 대답했습니다.