2017-11-20 4 views
0

최근에 일부 병렬 프로세스를 풀로 리팩터링하여 풀이 순수 프로세스의 거의 두 배가 걸린 것에 놀랐습니다. 동일한 수의 코어로 동일한 시스템에서 실행되고 있다고 가정하십시오.풀이 동일한 프로세스 수보다 느리다 이유

공유 의존성 :

여기

https://github.com/taynaud/python-louvain

from community import best_partition 

Process를 사용하여 빠른 구현 누군가가 풀을 사용하여 내 구현이 오래 걸리는 이유를 설명 아마도 몇 가지 조언을 제공 할 수 있기를 바랍니다. [UPDATE]는 여전히 신속 풀 구현 동일 액티브 프로세스의 수를 제어하기 위해 리팩토링 여기

processes = [] 
pipes = [] 

def _get_partition(send_end): 
    send_end.send(best_partition(a_graph, resolution=res, randomize=rand)) 

for idx in range(iterations): 
    recv_end, send_end = Pipe(False) 
    p = Process(target=_get_partition, args=(send_end,)) 
    processes.append(p) 
    pipes.append(recv_end) 

running_procs = [] 
finished_procs = [] 
while len(finished_procs) < iterations: 
    while len(running_procs) < n_cores and len(processes): 
     proc = processes.pop() 
     proc.start() 
     running_procs.append(proc) 

    for idx, proc in enumerate(running_procs): 
     if not proc.is_alive(): 
      finished_procs.append(running_procs.pop(idx)) 

for p in finished_procs: 
    p.join() 

partitions = [pipe.recv() for pipe in pipes] 

및 느린, Pool 구현이다.

는 수영장과 프로세스의 무리 사이에 차이가있을 때 보통 (가의 이익 중이 될 수 있음),이 데이터 세트
pool = Pool(processes=n_cores) 
results = [ 
    pool.apply_async(
     best_partition, 
     (a_graph,), 
     dict(resolution=res, randomize=rand) 
    ) for i in range(iterations) 
] 
partitions = [res.get() for res in results] 
pool.close() 
pool.join() 
+0

첫 번째 예에서는 잠재적으로 더 많은 프로세스를 생성하고 있습니다. – Shadow

+0

Shadow에 답해 주셔서 감사합니다. 저는 같은 시스템에서 실행 중이었고 풀은 장비가 제공해야하는 최대 코어 수를 사용하고있었습니다. – jfunk

+0

시간 측정에는 정확히 무엇이 포함되어 있습니까? 두 경우 모두 또는 전체 코드 스 니펫? – roganjosh

답변

1

입니다 :이 느린 상관없이 풀 주어 얼마나 많은 프로세스 아직 없습니다 결과를 정의하는 작업이 수행됩니다.

당신의 a_graph이 무엇인지 모르는 사이에, 저는 큰 일 이겠지요. 프로세스 모델에서는 하위 프로세스에서이 모델의 메모리 내 복사본을 사용합니다. 풀 모델에서는 호출 할 때마다 각 작업자에게 a_graph 복사본을 인수로 전송합니다. 이것은 실제로 대기열로 구현됩니다. 프로세스 모델에서 파이썬 인터프리터가 fork()을 호출하면 서브 프로세스는 C 레벨에서이 복사본을 얻는다. 이것은 대기열을 통해 큰 파이썬 객체, 사전, 배열 또는 무엇이든지 전송하는 것보다 훨씬 빠릅니다.

작업이 완료하는 데 아주 짧은 시간이 소요되면 반대가 될 수 있습니다. 이 경우 풀은 이미 실행중인 프로세스에 작업을 전달하므로 더 나은 솔루션입니다. 각 작업 후에 프로세스를 다시 만들 필요가 없습니다. 이 경우 단 몇 분만에 실행되는 많은 새 프로세스를 만드는 데 필요한 오버 헤드로 인해 프로세스 구현이 느려집니다.

내가 말했듯이, 이것은 순수한 추측이지만, 귀하의 예에서는 실제로 근로자에게 매개 변수로 전송하는 것과 의미있는 차이가 있습니다. 이는 설명 일 수 있습니다.

+0

설명 해 주셔서 감사합니다. – jfunk