뮤트 개발일지

AIFFEL 아이펠 39일차 본문

AIFFEL

AIFFEL 아이펠 39일차

박뮤트 2022. 2. 23. 12:49

컴퓨터 파워 UP

멀티태스킹

2가지 동작 방식이 있다.

1. 동시성(Concurrency): 하나의 processor가 여러가지 task를 동시에 수행하는 개념

2. 병렬성(Parallelism): 유사한 task를 여러 processor가 동시에 수행하는 것

=> 병렬성과 동시성이 함께 적용될 시 효율이 극대화된다.

 

동기Symchronous vs 비동기Asynchronous

바운드bound: 어떤 일을 바로 하지 못하고 대기해야 하는 일이 발생한 것

동기: 앞 작업이 종료되기를 기다렸다가 다음 작업을 수행하는 것, 어떤 일이 순차적으로 실행된다. 요청과 요청에 대한 응답이 연속적으로 실행된다.(따라서 요청에 지연이 발생하더라도 계속 대기한다.)

비동기: 바운드 되고 있는 작업을 기다리는 동안 다른 일을 처리하는 것, 어떤 일이 비순차적으로 실행된다. 요청과 요청에 대한 응답이 연속적으로 실행되지 않는다. 특정 코드의 연산이 끝날 때까지 코드의 실행을 멈추지 않고 다음 코드를 먼저 실행하며, 중간에 실행되는 코드는 주로 콜백함수로 연결하기도 한다.

 

I/O bound vs CPU bound

속도에 제한이 걸리는 2가지 상황

1. I/O bound: 입력과 출력에서의 데이터(파일)처리에 시간이 소요될 때

2. CPU bound: 복잡한 수식 계산이나 그래픽 작업과 같은 엄청난 계산이 필요할 때

 

프로세스process

프로그램을 구동하여 프로그램 자체와 프로그램의 상태가 메모리 상에서 실행되는 작업 단위

하나의 프로그램을 실행할 때, 운영체제는 한 프로세스를 생성한다. 프로세스는 운영체제의 커널에서 시스템자원(CPU, 메모리, 디스크) 및 자료구조를 이용한다.

 

스레드Thread

어떠한 프로그램 내, 특히 프로세스 내에서 실행되는 흐름의 단위

전용 메모리 공간(Heap)을 가진다. 이 때, 해당 프로세스 내의 스레드들은 이 메모리 공간을 공유하지만 다른 프로게스와는 공유하지 않는다. 하나의 프로그램에서 여러 개의 스레드가 병렬적으로 처리되기도 하고, 가벼운 프로그램은 하나의 스레드를 가지기도 한다.

 

프로파일링Profiling

코드에서 시스템의 어느 부분이 느린지, 혹은 어디서 RAM을 많이 사용하고 있는지를 확인하고 싶을 때 사용하는 기법

어플리케이션에서 가장 자원이 집중되는 지점을 정밀하게 찾아내는 기법, 즉, 코드의 병목bottleneck을 찾아내고 성능을 측정한다.

 

Scale-Up: 자원을 업그레이드, 최적화 시키는 것. 컴퓨터 한 대의 성능을 최적화 시키는 방법

Scale-Out: 자원을 확장시키는 것. 여러 대의 컴퓨터를 한 대처럼 사용하는 것

 

파이썬에서 멀티 프로세스 사용하기

p = mp.Process(target=delivery, args=())
p.start() # 프로세스 시작
p.join() # 실제 종료까지 기다림 (필요시에만 사용)
p.terminate() # 프로세스 종료

 

ProcessPoolExecutor 실습

https://docs.python.org/ko/3.7/library/concurrent.futures.html

 

concurrent.futures — 병렬 작업 실행하기 — Python 3.7.12 문서

소스 코드: Lib/concurrent/futures/thread.py와 Lib/concurrent/futures/process.py concurrent.futures 모듈은 비동기적으로 콜러블을 실행하는 고수준 인터페이스를 제공합니다. 비동기 실행은 (ThreadPoolExecutor를 사용

docs.python.org

1) 소수 판별 문제

import math
import concurrent

PRIMES = [
    112272535095293,
    112582705942171,
    112272535095293,
    115280095190773,
    115797848077099,
    1099726899285419]

2) 소수 판별 함수 is_prime

def is_prime(n):
    if n < 2:
        return False
    if n == 2:
        return True
    if n % 2 == 0:
        return False

    sqrt_n = int(math.floor(math.sqrt(n)))
    for i in range(3, sqrt_n + 1, 2):
        if n % i == 0:
            return False
    return True

3) 소수 판별 함수 호출

map()함수를 ProcessPoolExecutor()인스턴스에서 생성된 executor에서 실행시킨다.

concurrent.futures 라이브러리의 프로세스 풀에서 동작하게 하기 위해 with 문을 썼다.

def main():
    with concurrent.futures.ProcessPoolExecutor() as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))

- 프로파일링을 위한 시간 계산 코드 추가

- 단일처리로 수행했을 때의 코드 추가, 단일처리 프로파일링을 위한 시간 계산 코드 추가

import time

def main():
    print("병렬처리 시작")
    start = time.time()
    with concurrent.futures.ProcessPoolExecutor() as executor:
        for number, prime in zip(PRIMES, executor.map(is_prime, PRIMES)):
            print('%d is prime: %s' % (number, prime))
    end = time.time()
    print("병렬처리 수행 시각", end-start, 's')
    
    print("단일처리 시작")
    start = time.time()
    for number, prime in zip(PRIMES, map(is_prime, PRIMES)):
        print('%d is prime: %s' % (number, prime))
    end = time.time()
    print("단일처리 수행 시각", end-start, 's')

코드 실행

main()
병렬처리 시작
112272535095293 is prime: True
112582705942171 is prime: True
112272535095293 is prime: True
115280095190773 is prime: True
115797848077099 is prime: True
1099726899285419 is prime: False
병렬처리 수행 시각 1.9428431987762451 s
단일처리 시작
112272535095293 is prime: True
112582705942171 is prime: True
112272535095293 is prime: True
115280095190773 is prime: True
115797848077099 is prime: True
1099726899285419 is prime: False
단일처리 수행 시각 2.70733380317688 s

병렬처리로 수행하면, 1.94초가 걸리지만 단일처리로 하면 2.7초가 걸린다.

'AIFFEL' 카테고리의 다른 글

AIFFEL 아이펠 41일차  (0) 2022.02.25
AIFFEL 아이펠 40일차  (0) 2022.02.24
AIFFEl 아이펠 38일차  (0) 2022.02.22
AIFFEL 아이펠 37일차  (0) 2022.02.21
AIFFEL 아이펠 36일차  (0) 2022.02.18