파이썬
동적 타이핑, 인터프리터 언어.
동적타입 vs 정적타입
동적타입이라는것은 선언할때 자료형을 선언하지 않다는것이고, 인터프리터가 정의된 객체의 자료형을 알고있지않다는것을 의미한다.
자료형의 명시 여부는 처리속도에도 영향을 미치는데
자료형을 명시했다면 런타임과정에서 자료형타입에 맞게 바로 함수를 호출하면 되지만,
자료형을 명시하지않았다면 런타임과정에서 객체의 존재를 확인 → 객체의 자료형타입을 확인 ( PyObject_HEAD) → 자료형타입에 맞게 함수 호출 하는 과정을 거친다.
자료형을 명시했다면 ‘객체의 자료형을 판단하지 않고' 바로 타입형에맞게 함수를 사용가능하다는것이다.
이는 선언하는 과정에서도 차이나는데
## C언어
int a = 1;
int b = a+2;
## Python
a = 1
b = a+1
C언어는 int형이라는것을 알지만, Python은 객체가 있다는것만 안다.
인터프리터 형식 vs 컴파일 형식
인터프리터 형식의 특징은 ‘한줄한줄 실행할때마다 자료형과 자료정보를 찾는다' 라는거고
컴파일 형식은 ‘실행하기전에 모든 자료형과 자료정보를 확인하고, 실행한다' 라는거다.
한줄한줄씩 실행하면 왜 느릴까?
파이썬은 개체모델의 속성을 가지고있고, Garbage Collection의 정책때문이다.
개체모델의 비효율적 메모리 엑세스
파이썬은 아까 자료처리과정에서, 한줄씩 읽고 실행한다고 했다.
한줄씩 읽고, 객체를 확인하고, 자료형을 확인하고, 다시 인터프리터를 끄는것을 모든라인마다 반복하면 메모리소모가 더 클것이라고 알수있다.
Python GIL
파이썬은 인터프리터 언어로써, 인터프리터 형식으로 작동된다고했다.
Python인터프리터는 Python으로 작성된 코드를 한줄씩 읽고 실행하는 프로그램으로서
현재 프로그램의 표준 구현체로는 CPython이다.
GIL(Global Interpreter Lock) 은 Python의 객체들에 대한 접근을 보호하는 일종의 뮤텍스로서
여러개의 쓰레드가 파이썬 코드를 동시에 실행하지 못하게 막고있다.
하나의 프로세스 내에서 Python인터프리터는 한 시점에 하나의 쓰레드에 의해서만 실행이 가능하다는것을 의미한다.
그러나 이는 멀티쓰레딩이 불가능하다는것이 아니다.
원래 멀티코어라면, 멀티쓰레딩시에 여러개의 쓰레드가 여러코어상에서 병렬로 실행되는데, Python에서는 그러한 병렬실행이 불가능하다는 것뿐이다.
Garbage Collection
Python에서는 모든것은 객체로 존재하고, 각 객체는 참조횟수(Reference Count)를 저장하기 위한 필드를 가진다.
참조횟수는 객체를 가리키는 참조가 몇 개 존재하는지를 나타내는것으로, Python에서의 GarbageCollection은 참조횟수가 0이 되면 해당객체를 메모리에서 삭제시키는 메커니즘으로 동작하고 있다.
참조횟수에 기반하여 GarbageCollection을 진행하는 Python의 특성상, 여러개의 쓰레드가 Python인터프리터를 동시에 실행하면, 값이 올바르지 않게 읽히거나 쓰일수 있다.
이는 쓰레드끼리는 자원공유를 하고, 프로세스끼리는 독자적인 메모리 공간이 존재하기 때문이다. 이러한 상황을 Thread-safe하지 않다고 표현한다.
여러개의 쓰레드가 Python인터프리터를 동시에 실행하게 두면, 각 객체의 참조 횟수가 올바르게 관리되지못할수도 있어서, 이로 인해 Garbage Collection가 제대로 동작하지않을수도 있다.
Python 병렬처리
그래서 파이썬에서 병렬처리를 하려면 멀티프로세싱을 하는 방법으로 많이들 병렬성을 구현한다
한 프로세스의 여러 쓰레드들은 서로 자원을 공유하지만, 여러 프로세스들은 각자 독자적인 메모리 공간을 거쳐서 서로 자원을 공유하지 않다는점을 이용한다.
일반적으로 시스템 라이브러리인 multiprocessing 을 사용하기보단, RAY라이브러리를 사용해서 구현하는 것같다
RAY
분산 어플리케이션을 구현할수 있게 해주는 범용 API
multiprocessing라이브러리는 병렬처리를 위해서 소스코드자체를 바꿨어야했지만, RAY는 코드를 수정할필요가 없게 만들고. 또한 직렬화 오버헤드 문제를 가지지않습니다
직렬화 오버헤드
작업을 함께하는 여러개의 프로세스들이 시작하고, 작업을 넘겨주는 과정에서 발생하는 리소스소모
예제 )
프로세스1시작 → 프로세스1종료 && 프로세스2시작
→ 프로세스2종료 && 프로세스3시작
이때 생기는 대기시간 및 메모리 할당과정 등등을 오버헤드라고 표현한다
'CS지식' 카테고리의 다른 글
RAID 전략에 대해서 알아보기 (0) | 2022.11.12 |
---|---|
VM vs Container (0) | 2022.11.12 |
In-Memory 는 왜 쓸까? (0) | 2022.11.01 |
도커와 가상환경(VM)의 차이 (0) | 2022.07.04 |
캐시메모리가 빠른 이유 (0) | 2022.07.04 |