multiprocessing

우선 내가 multiprocessing을 사용하는 것은 여러 이미지 파일에서 동일한 처리를 한 번에 많이 시행하기 위함이다. 우선 이를 위하여 이미지 처리하는 부분을 따로 분리하여 함수로 지정하였다.

Pool 방법과 Process 방법이 있는데, Pool 방법이 나에게 더 맞는 것 같아서 이 방법으로 해보기로 했다. 그리고 Pool 방법에 map, async_map 등의 방법이 더 있다. 나는 병렬 처리 한 결과를 따로 받아서 처리하지 않기 때문에 코딩하기 쉬운 map 방법으로 선택하였다.

import multiprocessing

def find1(i):
    ~~~

multiprocessing.Pool(os.cpu_count()).map(find1, files)

os.cpu_count()는 현재 CPU의 코어 숫자를 확인하는 것이다. 메모리가 많이 필요한 분석은 아니기 때문에, 신속한 분석을 위해서 다 사용한다. files는 분석을 할 파일 목록들이다.

믿을 수 없게 저 간단한 방법으로 동시에 6개 파일을 처리할 수 있다. Python에 대한 xkcd의 유명한 내용인 https://xkcd.com/353/ 이 생각났다.

단일 코어를 사용하는 기존 방법 분석 때 제대로 확인 안했기는 하지만, 단일 파일 처리할 때와는 달리 core 에서 약 30~40% 정도는 system이 사용한다. 아마 60~70% 성능으로 6개를 분석하는 것이니까 대충 4배 정도의 속도 향상을 기대할 수 있을 것 같다. 하이퍼쓰레딩을 켜고 사용해 봤는데 40~50% 정도 사용에 12개 코어이다. 그런데 체감은 더 느린 것 같다. 그래서 다시 하이퍼쓰레딩을 껐다.

내가 불필요한 정보를 계속 기억하게 했는지, 시간이 지나면서 메모리가 증가하는 문제가 생겼다. 일단 저 병렬처리 부분이 종료되면 메모리가 다시 원상태로 돌아온다. 그래서 한 번에 분석할 파일 목록을 줄여서 처리하는 방법으로 메모리 누수 문제를 해결했다.

work_list_number = 400
for i in range(0, len(files), work_list_number):
    work_list = files[i:i+work_list_number]
    multiprocessing.Pool(os.cpu_count()).map(find1, work_list)