[분산 시스템] 2-4. Multi Processing vs Multi Threading vs Async

들어가며

이번 시간에는 CPU Bound Application과 I/O Bound Application을 만들어서 Multi Processing, Multi Threading, Async를 사용했을 때 어떤 방식이 더 효율이 좋은 지 비교해볼 것이다.

CPU Bound Application

CPU Bound Application은 300,001 ~ 300,030까지 그 보다 작은 수의 제곱을 더한 계산을 수행할 것이다.

EX) 300,001 - 1x1 + 2x2 + 3x3 ~ 300,001 x 300,001

import time

# 실행함수1(계산)
def cpu_bound(number):
    return sum(i * i for i in range(number))

# 실행함수2
def find_sums(numbers):
    result = []
    for number in numbers:
        result.append(cpu_bound(number))

    return result


def main():
    numbers = [3_000_000 + x for x in range(30)]
    
    # 실행시간 측정
    start_time = time.time()

    # 실행
    total = find_sums(numbers)

    print(f"Sum : {sum(total)}")

    # 실행 시간 종료
    duration = time.time() - start_time

    # 수행 시간
    print(f"Duration : {duration} seconds")

IO Bound Application

IO Bound Application은 아래 uuid를 제공하는 해외 사이트를 100번 접속해서 uuid를 받아오는 작업을 수행한다.

import requests
import time

URL = 'https://httpbin.org/uuid'


def fetch(session, url):
    with session.get(url) as response:
        print(response.json()['uuid'])


def main():
    with requests.Session() as session:
        for _ in range(100):
            fetch(session, URL)

if __name__ == "__main__":
	# 실행 시간 측정
    start_time = time.time()
    
    # 실행
    main()
    
    # 실행 시간 종료
    duration = time.time() - start_time
    
    # 수행 시간
    print(f"{duration} seconds")

Multi Processing & Multi Threading & Async 구현

각 어플리케이션에 Processing, Thread, Asyncio 라이브러리를 통해 다중 프로그래밍을 구현한다.

소스코드는 아래 깃허브 주소에서 확인!
https://github.com/gimseonjin/kumoh42_os


측정 시작

측정은 각각의 어플리케이션을 Sync, Multi Processing, Multi Threading, Async 방식으로 10회 실행, 수행 시간의 평균을 구해 순위를 매겨 최적의 수행 방식 선정!

CPU Bound Application

CPU Bound Application의 결과를 확인해보면 "Multi Processing" 방식이 가장 빠르다는 것을 확인할 수 있다.

사용하는 프로세스 개수가 늘어나면서 활용 가능한 CPU 자원이 늘어나고 Context Switching 횟수가 줄어들면서 성능이 개선된 것으로 추론 할 수 있다.

반면 Async(비동기) 방식을 살펴보면 오히려 Sync 방식을 사용한 것보다 더 오래 걸리는 것을 확인할 수 있다. 이처럼 잘못된 다중 프로그래밍 방식을 사용하면 오히려 성능이 저하되는 것을 확인할 수 있다.

IO Bound Application

IO Bound Application에서는 모든 방식이 성능 향상을 가져왔다. 다만 Multi Threading과 Async를 사용할 시 압도적으로 성능이 향상되는 것을 확인할 수 있다.

특히 Async는 Sync에 비해 20배 가량의 효율을 보이며 이를 통해 Web 영역에서 Async를 활용한 단일 스레드 & 단일 프로세스로도 충분히 좋은 성능의 서비스를 구현할 수 있다는 것을 확인했다.


결론

딥러닝이나 머신러닝처럼 CPU를 많이 사용하는 분야에서 왜 Multi Processing을 많이 사용하는 지에 대해 알 수 있었다.

Web, App 분야에서 왜 Multi Threading 기반(Spring boot)이 많은 지, 또 왜 최근 단일 프로세스, 단일 스레드 & Async 조합의 언어(EX : Node js, Flutter)가 많은 지 알 수 있었다.

그러면서 Web 분야에서 머신러닝을 활용할 경우 성능 향상을 어떻게 해야할 지, 또 단순 CRUD 기능을 가진 서버의 성능 향상은 Muti Threading or Async 말고 없는가에 대해 의문이 생긴다.

다음 시간부터는 Spring boot를 통해 CPU Bound Application & IO Bound Application Server를 구축해서 Artillery로 부하테스트를 해보면서 서버 인프라 측면에서의 성능 향상에 대해 공부해볼 것이다.

좋은 웹페이지 즐겨찾기