2014-09-04 2 views
0

파이썬 코드에 큰 파일을 입력하고 해당 출력 파일을 생성합니다. 그러나 너무 많은 시간이 걸리고 속도를 높이고 싶습니다.내 파이썬 코드를 병렬화하는 방법

지금은 큰 파일을 1000 개의 작은 파일로 분할했습니다. 나는 1000 개의 스레드를 시작할 작은 스크립트를 원한다. 각 스레드는 원래의 파이썬 코드를 사용하고 자체 출력 파일을 가지고있다.

누구나 샘플/예제 코드를 제공 할 수 있습니까? 1000 개 프로세서가없는 경우

+0

속도가 올라 가지 않아도됩니다 (많은 경우) ... 가능한 한 많은 부분으로 분할해야합니다 ... 그리고 다중 처리 라이브러리를 사용하십시오 ... 파이썬에서 스레드를 사용하는 유일한 이유는 당신이 GUI를 할 때 차단하고 싶지 않다면 ... 그렇지 않으면 당신은 동시 데이터 처리가 필요하다면 다중 처리를 사용해야합니다. –

+0

작업이 실제로 CPU (처리 중), 또는 I/O (파일 읽기 및 쓰기)에 의해 지배되고 있습니까? 일들을 병렬 처리하는 방법을 결정하기 전에 프로파일을 먼저 알아 내야합니다. – abarnert

+0

I/O로, 각 라인 비용은 4ms CPU입니다. I/O는 더 높아야한다고 가정합니다. – Jin

답변

1
  • , 1000 분할은 I/O가없는 처리를 병렬화,보다 효율적으로 차단 관리에 대한
  • 멀티 스레딩은 ... 관심 ... 반대로, 큰 오버 헤드가 없다 작업. 문제는 동일한 장치에서/O, 거기에 부하를 증가시키고 오버 헤드가 증가 할 것이다 더 만들기 (헤드가 이동, 캐싱 쓰레기 ...) I를하는 경우

은 당신이 검색하는 것은 더 멀티입니다 : https://docs.python.org/2/library/multiprocessing.html

+0

나는 본다. 고마워요. – Jin

1

multiprocessing으로 가기로 결정했다면 매우 유사한 방식으로 처리 할 것입니다. 이 같은 시도 할 수 있습니다 : 거의 확실하게 느린 것 아래로, 그 속도를하지 않습니다 1000 개 스레드를 사용하여,

import Queue 
from threading import Thread 

file_list = ['filea', 'fileb'] 

def do_stuff(q): 
    while True: 
     try: 
      file_name = q.get(False) 
     except Queue.Empty: 
      # Handle empty queue here 
      break 
     # do what ever you need here 
     print file_name 
     q.task_done() 

q = Queue.Queue(maxsize=0) 
num_threads = 2 

for x in file_list: 
    q.put(x) 

for i in range(num_threads): 
    worker = Thread(target=do_stuff, args=(q,)) 
    worker.setDaemon(True) 
    worker.start() 

q.join() 
+0

'multiprocessing' 라이브러리가 하나의 빌트인 (당신이 작성하지 않은 모든 종류의 기능을 추가합니다. 반환 값, 완료 신호와 대기 신호 등)과' concurrent.futures' (또는'futures' 백 포트)는 executor를 사용하기가 더 쉽습니다. – abarnert

+0

@abarnert 의견을 제시하기 위해 동의하지만, 단지 예일뿐입니다. – Vor

+0

좋습니다.하지만 몇 줄의 코드에서 몇 가지 예제로 코드를 작성하고 모든 것을 다룰 수있는 이유는 무엇입니까? – abarnert

5

먼저. 코드가 완전히 I/O 바운드 인 경우에도 1000은 많은 플랫폼의 스케줄러의 한계를 뛰어 넘고 있으며 실제 작업을 수행하는 것보다 컨텍스트 스위칭에 더 많은 시간을 할애 할 것입니다.

다음으로 코드가 CPU 바인딩 (즉, 메모리의 정보 처리) 또는 I/O 바인딩 (즉, 디스크 읽기 및 쓰기 대기)인지 여부를 알아야합니다.


코드가 CPU 바인딩되어 있고 CPU를 꽤 일관되게 유지할 수있는 경우 코어 당 정확히 하나의 스레드가 필요합니다. 그렇게하면 컨텍스트 스위칭의 최소량 (그리고 대부분의 작업이 변경 불가능하거나 비공유 값으로 수행된다고 가정 할 때 캐시 스 래싱)을 통해 최대 병렬 처리량을 얻을 수 있습니다.

(numpy와 같이 특수하게 설계된 C 확장자로 작업하지 않는 한) 이러한 스레드가 별도의 프로세스에 있어야합니다. 프로세스 당 하나의 스레드 만 파이썬 인터프리터를 한 번에 실행할 수 있기 때문에 글로벌 인터프리터 잠금.

그래서 원하는 것은 거의 확실히 프로세스 풀입니다. 가장 쉬운 방법은 concurrent.futures.ProcessPoolExecutor을 사용하고 max_workers 인수를 사용하는 것입니다 (16 자부터 시작하여 도움이되는지 위아래로 조정 해보십시오). 다른 한편으로는, 코드가 대부분이며, 경우


I/O 바인딩, 다음 몇 다스 스레드는 지연 예측할 특히, 합리적이지만, 동일한 프로세스에서하지 1000 스레드 것 하나의 스레드가 파이썬 인터프리터를 실행할 수 있고 다른 스레드는 모두 OS가 디스크 작업을 끝내기를 기다리고 있기 때문에 정상적으로 작동합니다.

따라서이 경우 concurrent.futures.ThreadPoolExecutor이 필요합니다.확실하지 않은, 먼저, 다음 ActivityMonitor를 사용하거나 윈도우가 자신의 프로세스 관리자 또는 300 개 옵션의 당신의 마음에 드는 호출 어떤 스레드 풀로 구축, 찾는 방법을 모르는 경우


리눅스가 실행되는 것을 지켜 보자. 하나의 코어가 100 %로 끝나고 다른 코어가 25 % 미만으로 끝나면 스레드를 사용하기에는 너무 CPU 중심적입니다. 다행스럽게도 프로세스 풀로의 전환은 ThreadPoolExecutorProcessPoolExecutor으로 대체하고 max_workers 인수를 제거하여 파이썬이 최상의 기본값을 선택하고 이제 완료되었습니다.


두 경우 모두 다른 샘플 코드를 요청할 필요가 없도록 문서의 예제가 충분합니다.

관련 문제