Python/Advanced

[Python 심화] Python의 GIL과 느린 이유

yubi5050 2022. 8. 24. 20:17

Python이 느린 이유

🎈 1. 파이썬은 C, Java와 달리 동적 타입 언어이다.

정적 타입 언어는 사전에 자료형을 명시하는 경우이고, 동적 타입 언어란 자료형을 명시하지 않는 경우의 언어이다. 아래 덧셈 연산으로 비교해보면 파이썬이 훨씬 더 절차가 복잡한 것을 알 수 있다. 

C언어 파이썬
int a=1; int b=2; int c = a+b; a=1 b=2  c=a+b
컴파일(자료형 판단 완료) => a에 1할당 => b에 2할당 => 덧셈 연산 호출 => 결과 c에 할당 a에 1할당 => a타입판단 => a 값 정수 1 설정 =>
b에 1할당 => b타입판단 => b 값 정수 2 설정 =>
덧셈 연산 호출 =>
객체 c 생성 => c자료형 정수 설정 => c 값 정수 3 설정

 

🎈 2. 파이썬은 인터프리터 언어이다.

파이썬은 기존의 컴파일 언어와 달리 그때 그때 한줄을 해석하고 일을 처리하기에 컴파일 언어보다 늦게 처리 된다.

 

 

🎈 3. 파이썬은 비효율적인 메모리 Access가 발생한다.

위 1. 의 예시 과정처럼, 파이썬 코드는 변수의 타입에 대한 판단이나, 판단한 타입을 검색 하는 과정에서 컴파일 언어에 비해 추가적인 메모리 사용량이 발생한다.

 

🎈 추가 정리

파이썬은 컴파일되지 않는 동적 타입으로, 정적인 코드를 컴파일시

컴파일러는 CPU가 특정 명령을 실행하는 방식을 포함한 많은 부분을 변경해서 최적화 가능한데

파이썬은 동적 타입언어 이기 때문에 최적화 알고리즘이 더 제 기능을 발휘하기 어렵다.

 

Python의 구현체 GIL 

🎈  1. GIL 이란?

GIL (Global Interpreter Lock)은 파이썬 인터프리터가 하나의 스레드로 하나의 바이트 코드를 실행 시킬 수 있게 하는 Lock을 지칭한다. 하나의 스레드에만 모든 자원에 대한 접근을 허락하고, 나머지 스레드는 동작을 못하게 한다.

 

예로 파이썬에서 멀티 스레딩 구현시, 오히려 단일 스레드보다 성능이 낮게 나오는데, 단일 스레드에서 GIL을 얻어 동작하고 작업을 끝내는 동안, 멀티 스레드의 경우 thread context switch에 따른 비용도 발생하기 때문이다.

 

단 항상 멀티 스레드가 느린 것은 아니고, Sleep을 인위적으로 줄 경우, 싱글 스레드는 Sleep 시간을 온전히 한 스레드가 다 부담하게 되는 반면, 멀티 스레드에서는 한 스레드가 Sleep을 부담 하는 동안 context switching을 거쳐 다른 스레드가 작업을 이어나가기 때문에 더 작업이 빨리 끝난다.

 

 

🎈  2. Python은 왜 GIL을 계속 사용하는가?

GIL 을 계속 사용하는 이유에는 Python의 GC(Garbage collection)와 Reference Counting을 통한 메모리 관리에 있다.

 

파이썬의 모든 변수는 Reference Count라는 해당 객체가 얼마나 참조되고 있는지에 대한 숫자를 가지고 있으며, 해당 숫자가 0이 되면 자동으로 메모리에서 해제 되는 방식으로 구현되어 있다.

 

그러다 보니, 만약 동시에 여러 스레드에서 해당 변수에 접근(Race condition)하는 상황이 발생하면, 객체의 참조가 살아 있음에도, 메모리 상에서 해제 되버리는 버그가 발생할 수 있다.

 

그렇다고 모든 변수(객체)의 Reference Count에 Mutex를 걸어 사용하기엔 해당 Count에 대한 수많은 Lock 획득/해제에 대한 성능 감소가 예상되기에, Referecne Count를 보호하기 위해서라도, GIL(인터프리터 자체를 잠궈버리는 방식)을 계속 사용하는 것

 

GIL 최종 정리

  • GIL은 Global Interpreter Lock으로 단일 스레드에 특화 되어 있다.
  • Python은 메모리 관리 방법으로 Reference Counting을 사용하고 0이 되면 자동으로 메모리를 해제한다.
  • Python은 메모리 관리 전략을 지키기 위해 GIL을 사용해 Interpreter 자체를 Lock 하는 방식을 채택