2012-07-26 3 views
3

나는 아주 기본적인 질문을하고 있을지 모르지만 나는 파이썬에서 간단한 병렬 응용 프로그램을 만드는 방법을 정말로 생각할 수 없다. 16 개의 코어가있는 시스템에서 스크립트를 실행 중이므로 모든 스크립트를 효율적으로 사용하고 싶습니다. 나는 16 개의 거대한 파일을 읽고 각각의 CPU가 하나의 파일을 읽고 그 결과를 병합하기를 원합니다.파이썬, 많은 파일을 읽고 결과를 병합

parameter1_glob=[] 
    parameter2_glob[] 


    do cpu in arange(0,16): 
     parameter1,parameter2=loadtxt('file'+str(cpu)+'.dat',unpack=True) 

     parameter1_glob.append(parameter1) 
     parameter2_glob.append(parameter2) 

내가 multiprocessing 모듈이 도움이 될 수도 있지만, 내가 뭘 원하는지에 적용하는 방법을 이해하지 수 있다고 생각한다 여기에 내가 뭘하고 싶은 것의 빠른 예를 제공합니다.

+0

[파이썬의 GIL에 대해 들었습니까?] (http://stackoverflow.com/questions/990102/python-global-interpreter-lock-gil-workaround-on-multiccore-systems-using-task) – tkone

+2

여러 스레드를 사용할 필요가 없습니다 ... 응용 프로그램은 CPU 바인딩이 아닌 디스크 바인딩됩니다. –

+2

@tkone는 : 빨리 디스크를 만들려고하고 있지 않다하더라도'multiprocessing'은 별도의 통역을 사용하여 GIL를 피할 수 있습니다. – geoffspear

답변

1

줄 단위로 병합 하시겠습니까? 코 루틴은 클래식 멀티 태스킹보다 I/O 바운드 애플리케이션에 더 흥미로운 경우가 있습니다. 발전기와 코 루틴을 연결하여 모든 종류의 라우팅, 병합 및 방송을 할 수 있습니다. 이 nice presentation by David Beazley으로 마음을 날려 보라.

당신은 싱크대로 코 루틴을 사용할 수 있습니다

가 (예를 dabeaz하기 위해 검증되지 않은 참조) :

# A sink that just prints the lines 
@coroutine 
def printer(): 
    while True: 
     line = (yield) 
     print line, 

sources = [ 
    open('file1'), 
    open('file2'), 
    open('file3'), 
    open('file4'), 
    open('file5'), 
    open('file6'), 
    open('file7'), 
] 

output = printer() 
while sources: 
    for source in sources: 
     line = source.next() 
     if not line: # EOF 
      sources.remove(source) 
      source.close() 
      continue 
     output.send(line) 
2

콜린 덩크 라우 (Colin Dunklau)가 자신의 의견에 대해 말한 것에 동의합니다.이 프로세스는 이러한 파일을 읽고 쓰는 데있어 병목 현상을 일으키며 CPU 요구량은 최소화됩니다. 17 개의 전용 드라이브가 있더라도 하나의 코어를 최대한으로 활용할 수는 없습니다. 또한 실제 질문에 접하는 것입니다 만, "거대한"파일을 메모리 제한 사항으로 사용하게 될 것입니다. 16 개의 파일을 배열로 메모리에로드 한 다음 다른 파일로 결합하면 메모리가 늘어납니다. 너는 가지고있다.

이 문제를 쉘 스크립팅하는 것이 더 좋은 결과를 얻을 수 있습니다. 특히, GNU sort은 메모리 효율적인 병합 정렬을 사용하여 하나 이상의 파일을 매우 빠르게 정렬합니다. Python 또는 대부분의 다른 언어로 작성된 가장 신중하게 작성된 응용 프로그램을 제외한 모든 파일보다 훨씬 빠릅니다.

나는 멀티 스레딩 작업을 피하는 것이 좋습니다. 최소한의 이점으로 복잡성을 극적으로 높입니다. 한 번에 메모리에 파일을 거의 보관하지 마십시오. 그렇지 않으면 파일이 빨리 사라집니다. 어쨌든, 당신은 절대적으로 2 개의 분리 된 디스크에서 읽기 및 쓰기 실행을 원할 것입니다. 같은 디스크에 동시에 읽고 쓰는 것과 관련된 속도 저하는 엄청나게 고통 스럽습니다.

0

을 각 파일의 결과가 좀 작은 것을 가정하면, 당신은 내 패키지 jug이 할 수 있습니다 :

from jug import TaskGenerator 
loadtxt = TaskGenerator(loadtxt) 

parameter1_glob=[] 
parameter2_glob[] 

@TaskGenerator 
def write_parameter(oname, ps): 
    with open(oname, 'w') as output: 
     for p in ps: 
      print >>output, p 

parameter1_glob = [] 
parameter2_glob = [] 

for cpu in arange(0,16): 
    ps = loadtxt('file'+str(cpu)+'.dat',unpack=True) 
    parameter1_glob.append(ps[0]) 
    parameter2_glob.append(ps[1]) 

write_parameter('output1.txt', parameter1_glob) 
write_parameter('output2.txt', parameter2_glob) 

지금, 당신은 몇 가지 jug execute 작업을 실행할 수 있습니다.

관련 문제