파이썬은 데이터 분석, 머신 러닝 등에 널리 사용되는 인기 있는 프로그래밍 언어이다. 이런 파이썬을 사용하는 프로젝트들은 종종 많은 양의 데이터를 처리해야 한다. 대용량의 데이터를 처리해야하는 프로젝트는 싱글 프로세서에서 시간이 많이 소요될 수 있다.
다행히 파이썬은 여러 CPU 코어를 사용하여 병렬로 코드를 돌릴 수 있게 하여 CPU의 퍼포먼스를 최대한 활용할 수 있는 방법을 제공한다. 멀티프로세싱(multi-processing)은 특정 유형의 파이썬 프로그램을 실행하는 데 걸리는 시간을 크게 줄일 수 있다.
이제 간단한 코드를 통해 멀티 프로세싱의 가장 기본이 되는 multiprocessing.Pool()를 사용하는 방법을 알아보자.
Python Multi-processing
먼저 코드를 살펴보자. 천천히 살펴보면 그리 어렵지 않은 코드이다.
import time
import multiprocessing
def square(number):
return number ** 2
if __name__ == '__main__':
numbers = range(1000000)
# Single-core processing
start_time = time.time()
results_single = []
for number in numbers:
result = square(number)
results_single.append(result)
end_time = time.time()
single_time = end_time - start_time
# Multi-core processing
start_time = time.time()
pool = multiprocessing.Pool()
results_multi = pool.map(square, numbers)
pool.close()
pool.join()
end_time = time.time()
multi_time = end_time - start_time
# Print results
print(f"Single core time: {single_time:.4f} seconds")
print(f"Multi-core time: {multi_time:.4f} seconds")
print(f"Speedup: {single_time/multi_time:.2f}x")
먼저 멀티프로세싱을 위해서는 multiprocessing을 임포트하자.
square 함수는 number을 입력받아 입력받은 값의 제곱을 뱉어낸다.
numbers는 0부터 999,999까지의 숫자이고
싱글 코어와 멀티 코어를 사용하여 모든 수를 제곱하는 시간을 각각 측정한 다음 비교해볼 것이다.
싱글 코어의 계산 결과는 results_single, 멀티 코어의 계산 결과는 results_multi에 저장된다.
여기까지만 들으면 쉽지만 정작 멀티프로세싱에 대한 부분인 Pool()와 map()이 무슨 일을 하는지는 아직 모른다.
이제 멀티 프로세싱 부분의 코드를 한 줄씩 살펴보자.
pool = multiprocessing.Pool()
이 라인에서 우리는 사용 가능한 코어 수로 된 Pool을 만들어 연산을 빠르게 하려고 한다.
아주 정확한 비유는 아니지만, 예를 들어, Pool(8)이라면 동시에 동일한 작업을 수행할 수 있는 싱글 코어가 8개 있다는 것이다.
results_multi = pool.map(square, numbers)
여기서 0부터 999,999까지의 숫자들을 나누어 8개의 프로세서들이 각각 일을 하도록 작업 세트를 준다.
각 프로세서들은 독립적, 병렬로 작업하므로 싱글코어보다 전체 연산을 빨리 끝낼 수 있다.
pool.close()
이 라인은 할당된 연산을 마친 각 프로세서들이 더이상 작업할 게 없으니 들어가 쉬라는 말과 같다.
pool.join()
각 프로세서마다 연산 시간이 차이날 수 있다.
여기서 코드의 다음 줄로 넘어가기 전에 다른 프로세서들도 연산을 마칠 때까지 기다리라는 것과 같다.
이제 직접 코드를 돌려보자.
실행 환경은 M1 pro 맥북이다.
~/Workspace/python ❯ python multi.py
Single core time: 0.1193 seconds
Multi-core time: 0.3145 seconds
Speedup: 0.38x
? 멀티코어가 더 느리다. 다시 돌려도 결과가 비슷하다.
아마 이 코드는 멀티 프로세싱에 필요한 과정들로 인해 멀티 코어에서 시간이 더 걸리는 것으로 판단된다.
numbers에 0을 하나 추가하여 0부터 9,999,999까지 제곱 연산을 시켜보자.
~/Workspace/python ❯ python multi.py
Single core time: 1.1023 seconds
Multi-core time: 0.6382 seconds
Speedup: 1.73x
멀티 코어가 약 1.73배 시간적으로 빠르다. 나름 기대에 걸맞는 결과이다.
m1칩의 성능에 대해 감탄하면서 Intel(R) Xeon(R) CPU E5-2698 v4 @ 2.20GHz으로도 원래 코드를 돌려보자.
➜ ~ python multi.py
Single core time: 0.7772 seconds
Multi-core time: 0.5191 seconds
Speedup: 1.50x
멀티 코어로 작업했을 때 1.5배 더 빠른 것을 확인할 수 있다.
살펴본 것처럼 멀티 프로세싱은 속도를 크게 높일 수 있다.
이 외에도 파이썬에서 멀티 프로세싱을 위한 다른 도구들도 많이 있다.
그러나 어떤 특정 문제에 대한 최적의 프로세서 수는 사용 가능한 CPU 코어 수, 메모리, 코드의 특징 등 여러 요인에 따라 달라진다.
경우에 따라 프로세서를 너무 많이 사용하면 오버헤드가 증가하고 공유 리소스에 대한 병목이 발생하여 전체 실행 시간이 느려질 수 있다.(위의 경우 처럼)
따라서 여러 프로세서를 사용할 때 다양한 풀 크기를 실험해가면서 최적의 구성을 찾는 것이 중요하겠다.
'머신 러닝 > Python' 카테고리의 다른 글
| [ChatGPT] 파이썬으로 챗GPT 텔레그램 봇 직접 만들기 / ChatGPT Telegram Bot using Python (2) | 2023.03.28 |
|---|---|
| [KakaoTalk] 파이썬으로 카카오톡 메시지 봇 만들기 (5) | 2023.02.23 |
| [Python] 파이썬 가상환경 구축 / Build a Virtual Environment (1) | 2023.02.15 |
| [Python] pip 설치하기, Homebrew 설치하기 / Installing pip (pip, pip3) (0) | 2023.02.13 |
| [Python] 파이썬3 설치하기, 파이썬 버전 확인 / Installing Python3 (0) | 2023.02.12 |