[PYTHON] NumPy 대 다중 처리 및 mmap
PYTHONNumPy 대 다중 처리 및 mmap
파이썬의 멀티 프로세싱 모듈을 사용하여 대다수의 배열을 병렬로 처리하고 있습니다. 배열은 마스터 프로세스에서 numpy.load (mmap_mode = 'r')를 사용하여 메모리 맵핑됩니다. 그 후, multiprocessing.Pool () 프로세스를 포크 (전설).
나는 다음과 같은 행을 제외하고는 모든 것이 잘 작동하는 것처럼 보인다.
단위 테스트 로그에. 그럼에도 불구하고 테스트는 잘 통과합니다.
무슨 일이 벌어지는 지 알아?
Python 2.7.2, OS X, NumPy 1.6.1 사용.
최신 정보:
일부 디버깅 후 Pool.imap 호출에 대한 입력으로 메모리 매핑 된이 numpy 배열 (작은 조각)을 사용하는 코드 경로에 대한 원인을 찾아 냈습니다.
분명히 "문제"는 다중 처리 방식과 관련이 있습니다 .Pool.imap은 입력을 새 프로세스에 전달합니다. 즉, pickle을 사용합니다. mmaped numpy 배열에서는 작동하지 않으며, 내부에서 오류로 연결되는 부분이 있습니다.
로버트 커른 (Robert Kern)이이 문제를 다루는 것으로 보입니다. 그는 메모리 매핑 된 배열에서 가져온 imap 입력에 대한 특수 코드 경로를 만드는 것이 좋습니다. 생성 된 프로세스에서 동일한 배열을 수동으로 메모리 매핑합니다.
이것은 오히려 오류와 여분의 메모리 복사본으로 살기 때문에 너무 복잡하고 추한 것입니다. 기존 코드를 수정하는 데 더 가벼운 다른 방법이 있습니까?
해결법
-
==============================
1.내 평소 접근 (여분의 메모리 복사본을 가지고 살 수있는 경우)은 한 프로세스에서 모든 IO를 수행 한 후 작업자 스레드 풀로 보내야합니다. memmapped 배열의 조각을 메모리에로드하려면 x = np.array (data [yourslice]) (data [yourslice] .copy ()는 실제로이 작업을 수행하지 않으므로 혼동을 일으킬 수 있습니다.)
내 평소 접근 (여분의 메모리 복사본을 가지고 살 수있는 경우)은 한 프로세스에서 모든 IO를 수행 한 후 작업자 스레드 풀로 보내야합니다. memmapped 배열의 조각을 메모리에로드하려면 x = np.array (data [yourslice]) (data [yourslice] .copy ()는 실제로이 작업을 수행하지 않으므로 혼동을 일으킬 수 있습니다.)
먼저 몇 가지 테스트 데이터를 생성 해 봅시다.
import numpy as np np.random.random(10000).tofile('data.dat')
다음과 같이 오류를 재현 할 수 있습니다.
import numpy as np import multiprocessing def main(): data = np.memmap('data.dat', dtype=np.float, mode='r') pool = multiprocessing.Pool() results = pool.imap(calculation, chunks(data)) results = np.fromiter(results, dtype=np.float) def chunks(data, chunksize=100): """Overly-simple chunker...""" intervals = range(0, data.size, chunksize) + [None] for start, stop in zip(intervals[:-1], intervals[1:]): yield data[start:stop] def calculation(chunk): """Dummy calculation.""" return chunk.mean() - chunk.std() if __name__ == '__main__': main()
그리고 대신 np.array (data [start : stop])를 사용하기로 전환하면 문제를 해결할 수 있습니다.
import numpy as np import multiprocessing def main(): data = np.memmap('data.dat', dtype=np.float, mode='r') pool = multiprocessing.Pool() results = pool.imap(calculation, chunks(data)) results = np.fromiter(results, dtype=np.float) def chunks(data, chunksize=100): """Overly-simple chunker...""" intervals = range(0, data.size, chunksize) + [None] for start, stop in zip(intervals[:-1], intervals[1:]): yield np.array(data[start:stop]) def calculation(chunk): """Dummy calculation.""" return chunk.mean() - chunk.std() if __name__ == '__main__': main()
물론 이것은 각 청크의 여분의 메모리 내 복사본을 만듭니다.
결국에는 memmapped 파일을 전환하고 HDF와 같은 파일로 쉽게 전환 할 수 있습니다. 데이터가 다차원 인 경우 특히 그렇습니다. (필자는 h5py를 권하고 싶지만 데이터가 "테이블과 같은"경우 pyTables가 좋습니다.)
어쨌든 행운을 비네!
from https://stackoverflow.com/questions/9964809/numpy-vs-multiprocessing-and-mmap by cc-by-sa and MIT license
'PYTHON' 카테고리의 다른 글
[PYTHON] 바이트 파일에서 PIL 이미지 열기 (0) | 2018.10.27 |
---|---|
[PYTHON] multiprocessing.Pool ()은 일반 함수를 사용하는 것보다 느립니다. (0) | 2018.10.27 |
[PYTHON] 큰 문서에서 전자 메일 하위 문자열 추출 (0) | 2018.10.27 |
[PYTHON] 어떻게 numpy 배열을 "확장"할 수 있습니까? (0) | 2018.10.27 |
[PYTHON] Python + Selenium + PhantomJS에서 PDF로 렌더링 (0) | 2018.10.27 |