1

나는 대학 신입생이며 파이썬 초보자이기 때문에 나와 함께 곰. 일부 행렬 작업을 병렬 처리하려고합니다.병렬화 된 파이썬 코드에서 메모리 공유

def testfunc(connectionMatrix, qCount, iCount, Htry, tStepCount): 
     test = connectionMatrix[0:qCount,0:iCount].dot(Htry[tStepCount-1, 0:iCount]) 
     return test 

    f1 = job_server.submit(testfunc, (self.connectionMatrix, self.qCount, self.iCount, self.iHtry, self.tStepCount), modules = ("scipy.sparse",)) 
    f2 = job_server.submit(testfunc, (self.connectionMatrix, self.qCount, self.iCount, self.didtHtry, self.tStepCount), modules = ("scipy.sparse",)) 
    r1 = f1() 
    r2 = f2() 
    self.qHtry[self.tStepCount, 0:self.qCount] = self.qHtry[self.tStepCount-1, 0:self.qCount] + self.delT * r1 + 0.5 * (self.delT**2) * r2 

X 축 및 Y 축상의 백분율 고속화에 행렬의 크기가 정상 커브가 보인다 : 여기 ParallelPython 모듈을 사용하여 내 시도이다. 그것은 100x100 매트릭스에서 30 %의 속도 증가로 모자를 씌운 것 같습니다. 작고 큰 행렬은 증가가 적고 행렬이 충분히 작고 충분한 행렬을 사용하면 직렬 코드가 더 빠릅니다. 제 생각에 문제는 논쟁이 지나가고 있다는 것입니다. 큰 매트릭스를 복사하는 오버 헤드는 실제로 작업 그 자체보다 오래 걸립니다. 이 문제를 해결하려면 어떻게해야합니까? 메모리 공유를 통합하고 참조로 행렬을 전달하는 방법이 있습니까? 보시다시피, 인수가 수정되어 읽기 전용 액세스가 될 수 없습니다.

감사합니다.

+0

와우, 신입생 프로그래밍이 내 하루보다 _easier_라고 생각했습니다. 표준 라이브러리의 절반만으로 C 또는 기괴한 리스프 (lisp) 방언 대신 파이썬을 사용한다는 사실은 여러분이 더 재미있는 프로그램을 작성할 수 있음을 의미합니다. :) – abarnert

+0

나는 내 머리 위로 일종의이지만, 나는 중요한 프로그램 경험을 가진이 여름 프로그램에 적용한 유일한 사람이라고 믿습니다. 그래서 나는 유일한 선택이었고 이상적이었습니다. 그러나, 나는 아직도 아주 근사하다. – Nino

답변

1

글쎄요, ParallelPython의 요점은 스레드, 프로세스 또는 심지어 여러 컴퓨터에 분산되어 있는지 상관하지 않는 코드를 작성하고 메모리 공유를 사용하면 추상화가 깨질 수 있다는 것입니다.

하나의 옵션은 공유 파일 시스템에서 파일과 같은 것을 사용하는 것입니다. 공유 파일 시스템에서 각 작업자의 파일을 mmap합니다. 물론 더 복잡하고, 더 좋든 나쁘 든간에 파일 시스템, 프로토콜 공유 및 네트워크에 대한 많은 세부 사항에 의존 할 것이지만 옵션입니다.

분산 처리 옵션을 포기할 경우 다중 처리. 배열 (또는 다중 처리, 값 또는 다중 처리. 공유 유형)을 사용하여 공유 메모리에 액세스 할 수 있습니다. 그러나이 시점에서 작업 배포를 위해 ParallelPython 대신 멀티 프로세싱을 사용하는 것이 좋습니다. 멀티 프로세싱은 표준 라이브러리의 일부이며보다 강력한 API를 사용하므로 명시 적으로 ParallelPython의 한 가지 주요 이점을 포기합니다 .

두 가지 중에서 가장 나쁜 두 가지 옵션을 여러 가지 방법으로 결합 할 수 있지만 기존 코드를 변경해야 할 필요가 거의없는 점에서 가장 좋습니다. 로컬 파일을 사용하고 mmap합니다.

그러나이 작업을 수행하기 전에 프로파일 링을 고려하여 매트릭스를 복사하는 것이 실제로 병목 현상인지 확인하는 것이 좋습니다. 그리고, 그렇다면 전체 매트릭스를 복사하는 대신 각 작업이 필요로하는 부분을 복사하는 알고리즘 픽스가 있는지 고려해 볼 수 있습니다. (그게 의미가 있는지 여부는 각 직업이 필요로하는 부분이 모든 것보다 훨씬 적은지 여부에 달려 있습니다.)

+0

솔직히 말해서, 복사가 속도 저하이지만 프로파일 링 할 때'thread.lock '객체'의'{method 'acquire'}'와'{cPickle.dumps} '는 시간의 66 %를 차지합니다. 전체 스크립트를 실행하십시오. 나는 이것이 이들 산란과 복사를 가정했다. 여름 프로젝트의 최종 목표는 여러 대의 기계를 사용하는 것이므로 다중 처리 모듈은 작동하지 않습니다. 특정 부분 만 복사하는 경우, 작은 블록으로 작업 한 다음 다시 결합하는 행렬 작업을 다시 작성하려고 할 수 있습니다. 그게 당신이 의미 한 것입니까? – Nino

+1

자물쇠는 복사와 관련이 없지만 cPickle.dumps는 거의 확실합니다. 아이들을 산란하기 전에 매트릭스를 수동으로 pickleing 한 다음 pickle을 공유하고 (아이들에게 수동으로 unpickle) 수동으로 시간을 절약 할 수 있습니다.또는 일반적인 산세보다 더 빨리 그리고/또는보다 간결하게 표현할 수 있습니다. 하지만 처음에는 ... 전체 프로세스의 66 %, 또는 부모 프로세스 자체의 시간 중 66 %만이 확실합니까 (실제 작업은 거의 이루어지지 않을 수 있습니다)? 마지막으로, 네, 작은 블록에서 작동하도록 작업을 다시 작성하는 것이 그럴듯한 것이라면 제가 의도 한 바였습니다. – abarnert

+0

아, 최종 목표가 클러스터 된 메모리 공유 (파이썬에서 액세스 할 수 있음)가 아닌 한 클러스터를 사용하는 것이면 분명히 최종 버전에서 공유 메모리를 사용할 수 없기 때문에 분명히하지 않을 것입니다. 이 예비 버전에 사용하기 위해 노력하지 않습니다. 공유 파일 시스템과 mmap은 그만한 가치가있을 수 있지만 실제로 클러스터에서 사용하지 않으면 성능 테스트가 어려울 수 있습니다. – abarnert