파이썬에서 c언어를 사용하여 높은 연산 성능을 이끄는데 좋지만 비용이 매우 크다.
파이썬의 concurrent.futures 내장 모듈을 통해 사용할 수 있는 multiprocessing내장모듈이 어려운 문제를 풀기위한 해결책일 수 있다.
ThreadpoolExecuter 모듈을 이요하면 CPU코어를 활용할 수 있다.
- 주 인터프리터와 자식 프로세스는 별도 수행을 한다.
예를 들어 계산이 많이 필요한 작업을 여러 CPU 코어를 활용해 파이썬으로 실행하고 싶다고 하자.
- 계산이 많이 필요한 알고리즘을 대신해 여기서는 두 수의 최대공약수(GCD)를 구하는 구현을 사용한다.
# mymodule.py
def gcd(pair):
a, b = pair
low = min(a, b)
for i in range(low, 0, -1):
if a % i == 0 and b % i == 0:
return i
assert False, '도달할 수 없음'
#기존 순차적 계산
# run_serial.py
import my_module
import time
NUMBERS = [
(1963309, 2265973), (2030677, 3814172),
(1551645, 2229620), (2039045, 2020802),
(1823712, 1924928), (2293129, 1020491),
(1281238, 2273782), (3823812, 4237281),
(3812741, 4729139), (1292391, 2123811),
]
def main():
start = time.time()
results = list(map(my_module.gcd, NUMBERS))
end = time.time()
delta = end - start
print(f'총 {delta:.3f} 초 걸림')
if __name__ == '__main__':
main()
총 1.301 초 걸림
# run_threads.py
import my_module
from concurrent.futures import ThreadPoolExecutor
import time
NUMBERS = [
(1963309, 2265973), (2030677, 3814172),
(1551645, 2229620), (2039045, 2020802),
(1823712, 1924928), (2293129, 1020491),
(1281238, 2273782), (3823812, 4237281),
(3812741, 4729139), (1292391, 2123811),
]
def main():
start = time.time()
pool = ThreadPoolExecutor(max_workers=2)
results = list(pool.map(my_module.gcd, NUMBERS))
end = time.time()
delta = end - start
print(f'총 {delta:.3f} 초 걸림')
if __name__ == '__main__':
main()
총 1.292 초 걸림
ProcessPoolExecutor 클래스는 프로세스 풀을 사용하여 호출을 비동기적으로 실행하는 Executor 서브 클래스입니다. ProcessPoolExecutor 는 multiprocessing 모듈을 사용합니다. 전역 인터프리터 록 을 피할 수 있도록 하지만, 오직 피클 가능한 객체만 실행되고 반환될 수 있음을 의미합니다.
# run_parallel.py
import my_module
from concurrent.futures import ProcessPoolExecutor
import time
NUMBERS = [
(1963309, 2265973), (2030677, 3814172),
(1551645, 2229620), (2039045, 2020802),
(1823712, 1924928), (2293129, 1020491),
(1281238, 2273782), (3823812, 4237281),
(3812741, 4729139), (1292391, 2123811),
]
def main():
start = time.time()
pool = ProcessPoolExecutor(max_workers=2) # 이 부분만 바꿈
results = list(pool.map(my_module.gcd, NUMBERS))
end = time.time()
delta = end - start
print(f'총 {delta:.3f} 초 걸림')
if __name__ == '__main__':
main()
총 0.822 초 걸림