0

각 작업에서 첫 번째 단계로 ~ 500 개의 이미지가 있으며 ndimage.filters 아래의 필터는 1 개의 코어 만 사용하는 것으로 보입니다. 나는 multiprocessing.queue와 함께 multiprocessing.pool과 multiprocessing.process를 시도했다. 둘 다 작동했지만 단일 프로세스를 사용하는 것보다 훨씬 느리게 실행되었습니다. 그 이유는 피클 및 간접비 가능성이 매우 높았 기 때문입니다. 실제 데이터를 각 작업자에게 전달하는 대신 각 작업자 내에서 가짜 데이터를 생성하면 다중 처리로 실제로 성능이 크게 향상되었습니다.저효율 파이썬 병렬/다중 처리 (이미지 컨볼 루션)

저는 Windows 컴퓨터에서 스파이더를 실행 중이므로 코드를 다른 컴퓨터의 다른 사람에게 전달하므로 파이썬을 다시 컴파일하고 낮은 수준의 조정을 수행 할 수 없습니다.

matlab에서 convolution은 멀티 코어를 투명하게 사용하며 parfor는 오버 헤드를 적절하게 처리합니다. 파이썬에서 다중 처리 컨볼 루션을 실현하는 아이디어 또는 제안? 미리 많은 감사드립니다!

+0

자신의 이미지 데이터를 직접 산란하고 그 중에서 무엇이 나오는지보십시오. Pickle은 실제로 매우 효율적이며 이진 데이터를 다시 보지 않습니다. 그러나 pickle'd 객체가 참조하는 객체도 절인됩니다. 나는 당신이 실제로 당신의 서브 프로세스에 엄청난 양의 것을 보내고 있다고 의심 할 것이다. – user2722968

답변

0

작업이 numpy/scipy heavy 인 경우 다중 처리가 좋지 않은 것으로 보입니다. 대부분의 numpy/scipy 함수는 GIL의 영향을받지 않기 때문에 멀티 프로세싱 대신 멀티 스레딩을 사용해야했습니다. 가벼운 오버 헤드로 인해 멀티 프로세싱이 멀티 프로세싱보다 우위에 있기 때문입니다.

가장 중요한 점은 멀티 스레드가 단일 스레드보다 빠릅니다.

import Queue 
import threading 
import numpy as np 
from scipy import ndimage  
import time 

repeats = 24 

def smooth_img(q,im): 
    im_stack_tmp = ndimage.filters.gaussian_laplace(im, 2.) 
    q.put(im_stack_tmp) 


im_all = [None]*repeats 
im_all_filtered = [None]*repeats 

for j in range(repeats): 
    im_all[j] = np.random.randn(2048,2048) 

start = time.time() 
for j in range(repeats): 
    im_all_filtered[j] = ndimage.filters.gaussian_laplace(im_all[j], 2.) 
print 'single thread: '+str(time.time()-start) 


start = time.time() 
q = Queue.Queue() 
for im in im_all: 
    t = threading.Thread(target=smooth_img, args = (q,im)) 
    t.daemon = True 
    t.start() 
for j in range(repeats): 
    im_all_filtered[j] = q.get() 
print 'multi thread: '+str(time.time()-start)