2009-10-19 2 views
10

다음 코드는 내 게으른 두 번째 CPU 코어가 작동하도록 작성했습니다. 코드는 기본적으로 디렉토리 계층 구조에서 원하는 "바다"파일을 찾은 다음 나중에 이진 "바다"파일을 처리하여 50에서 100 개의 텍스트 및 이진 파일을 생성하는 외부 스크립트 세트를 실행합니다. 문제의 제목은 처리 속도를 높이기 위해 병렬 방식으로 제안됩니다.멀티 프로세싱 작업자 풀 사용

이 질문은 "Cannot start ipcluster"이라는 제목의 IPython 사용자 목록에 대한 긴 토론에서 기인합니다. IPython의 병렬 처리 기능에 대한 나의 실험부터 시작한다.

이 코드는 올바르게 실행되지 않습니다. "바다"파일을 포함하는 폴더에 "바다"파일 만있는 경우 스크립트는 외부 스크립트 실행을 완전히 수행하지 않고 실행을 완료합니다. (30 ~ 50 개의 외부 스크립트가 있지만 외부 스크립트 체인에서 첫 번째 스크립트를 실행 한 후에 만 ​​다중 처리가 가능합니다.) 흥미롭게도이 스크립트를 이미 처리 된 폴더 ("sea"파일 미리 처리하고 출력 파일은 이미 해당 폴더에 있음) 실행되면 선형 처리 타이밍과 관련하여 약 2.4 ~ 2.7X의 속도 향상을 얻습니다. 내 노트북에는 코어 2 듀오 2.5GHz CPU 만 있기 때문에 그다지 기대하지는 않습니다. CUDA 기반 GPU를 사용하고 있지만 현재의 병렬 컴퓨팅 문제와는 아무런 관련이 없습니다.

이 문제의 근원은 무엇이라고 생각하십니까?

모든 의견과 제안에 감사드립니다.

1) 당신이 pathfiles을 인쇄 한 :

#!/usr/bin/env python 

from multiprocessing import Pool 
from subprocess import call 
import os 


def find_sea_files(): 

    file_list, path_list = [], [] 
    init = os.getcwd() 

    for root, dirs, files in os.walk('.'): 
     dirs.sort() 
     for file in files: 
      if file.endswith('.sea'): 
       file_list.append(file) 
       os.chdir(root) 
       path_list.append(os.getcwd()) 
       os.chdir(init) 

    return file_list, path_list 


def process_all(pf): 
    os.chdir(pf[0]) 
    call(['postprocessing_saudi', pf[1]]) 


if __name__ == '__main__': 
    pool = Pool(processes=2)    # start 2 worker processes 
    files, paths = find_sea_files() 
    pathfile = [[paths[i],files[i]] for i in range(len(files))] 
    pool.map(process_all, pathfile) 
+0

: 다음은 오류의 단지 부분이다. 표시된 바와 같이 IDL 실행은 혼란스럽고 올바른 결과를 얻을 수 없습니다. [gsever @ ccn partest] $ python proall3.py PID : 17722 PID : 17723 IDL 버전 7.1 (Linux x86 m32). (c) 2009, ITT 시각 정보 솔루션 IDL 버전 7.1 (linux x86 m32). (c) 2009, ITT Visual Information Solutions % 파일 상태를 가져올 수 없습니다. 단위 : 0, 파일 : 잘못된 파일 설명자 –

답변

6

. 다중 처리 모듈에는 필요한 경우 서브 프로세스에 대한 로깅이 있습니다. 문제를 좁힐 수있는 코드를 단순화했기 때문에, 난 그냥 같은 몇 가지 인쇄 문으로 디버깅 할 것이다 (또는 당신은 PF 배열을 PrettyPrint 수) :


def process_all(pf): 
    print "PID: ", os.getpid() 
    print "Script Dir: ", pf[0] 
    print "Script: ", pf[1] 
    os.chdir(pf[0]) 
    call(['postprocessing_saudi', pf[1]]) 


if __name__ == '__main__': 
    pool = Pool(processes=2) 
    files, paths = find_sea_files() 
    pathfile = [[paths[i],files[i]] for i in range(len(files))] 
    pool.map(process_all, pathfile, 1) # Ensure the chunk size is 1 
    pool.close() 
    pool.join() 

내가 가지고 파이썬의 버전 2.6.4로 이것을 달성했다.대신에 내가 즉 process_raw postprocessing_saudi의 일부 하위 스크립트를 호출하려고 나는 이상한 오류가 실행할 때, 상단 외부 스크립트를 호출

+0

스크립트가 첫 번째 디렉토리를 방문하고 외부 처리 프로세스를 시작하지 않고 스크립트가 두 번째 디렉토리로 이동하여 거기에서 첫 번째 파일을 처리하려고 시도합니다. [gsever @ ccn partest] $ python proall3.py PID : 10723 스크립트 DIR :/홈/gsever/데스크탑/partest/20090317_131342/후 처리 스크립트 : 09_03_17_13_13_42.sea PID : 10724 스크립트 디렉토리 :/홈/gsever/데스크탑/partest/20090318_075533/후 처리 스크립트 : 09_03_18_07_55_33.sea 09_03_18_07_55_33를 처리 .sea 파일 ....................... 09_03_17_13_13_42.sea 파일 처리 중 .................. ..... 완료 –

+0

다시 외부 스크립트 ch를 제대로 적용하지 않으면 실행이 실패합니다. 각 바다 파일에 없습니다. 나는 여전히이 문제가 파이썬의 멀티 프로세싱 모듈과 관련이 있다고 생각한다. 정확한 문제를 파악하기 위해 더 많은 의견을 듣게되어 기쁩니다. –

3

내가 생각할 수있는 몇 가지가있다? 그것들이 모두 적절하게 생성되었는지 확신합니까?

a) 귀하의 os.walk가 약간 재미 있습니다. dirs.sort()는 괜찮을 것이지만, 상당히 불필요하게 보인다. os.chdir()은 일반적으로 사용되어서는 안됩니다. 복원 이어야합니다. 일반적으로 init에 루트를 추가해야합니다.

2) python2.6에서 다중 처리가 발생하여 풀에서 하위 포어를 생성하는 데 문제가 있음을 확인했습니다. (특히 스크립트에서 다중 프로세스를 사용하여 하위 프로세스를 생성하는 경우 해당 하위 프로세스에서 다중 프로세스 (풀이 잠겨 있음)를 올바르게 사용할 수 없었습니다. 멀린 프로세싱 백 포트가있는 python2.5를 사용해보십시오.

3) picloud의 cloud.mp 모듈 (다중 처리를 래핑하지만 풀을 다르게 처리 함)을 시도하고 이것이 작동하는지 확인하십시오.

당신은

cloud.mp.join(cloud.mp.map(process_all, pathfile)) 

(면책 조항 : 나는 PiCloud의 개발자 중 하나입니다) 할 것이라고 나는 작업자 프로세스에 무슨 일이 일어나고 있는지에 대한 더 나은 느낌을 얻기 시작하는 것

+0

1) 예, 경로가 모두 정확합니다. 필자는 IPython의 병렬 처리 기능을 사용하여 동일한 경로를 테스트하고 기본 스크립트는 폴더를 통과하여 해당 스크립트를 제대로 실행하여 바다 파일을 완전히 후 처리합니다. a) sort()는 Fedora 파일 시스템 (ext4)의 해결 방법입니다. 그것없이 os.walk()는 폴더를 임의로 방문합니다. 2) 2.5를 살펴 보겠습니다. 지금 당장 2.6.0을 사용합니다. 3) 제안에 감사드립니다. 시도해 볼 것이지만 다른 사람들이 쉽게 스크립트를 실행할 수 있도록 외부 요구 사항을 추가하지 않는 경향이 있습니다. –

관련 문제