Published on

GIL 제거된 Python 3.14t-dev 멀티스레딩 테스트

Authors
  • avatar
    Name
    devnmin
    Twitter

GIL 제거된 Python 3.14t-dev 멀티스레딩 테스트

안녕하세요, Python 개발자라면 한 번쯤 "GIL(Global Interpreter Lock)"이라는 단어를 들어봤을 것입니다. 멀티스레딩을 사용하더라도 병렬 처리가 안 되는 Python의 구조적 한계로 여겨졌던 GIL. 그런데 Python 3.14에서는 실험적으로 GIL을 제거한 버전(3.14t-dev)이 등장했습니다. 이번 글에서는 해당 버전을 직접 설치하고, 멀티스레딩 환경에서 어떤 변화가 있었는지 테스트를 통해 직접 확인해보겠습니다.

1. GIL이란 무엇인가? 🔒

GIL(Global Interpreter Lock)은 CPython 인터프리터에서 동시성 문제를 피하기 위해 사용되는 일종의 전역 락입니다. 하나의 Python 프로세스에서 여러 스레드가 실행되더라도, 한 번에 하나의 스레드만 Python 바이트코드를 실행할 수 있도록 제한합니다.

이로 인해 I/O 작업에서는 멀티스레딩이 효과를 발휘하지만, CPU 바운드 연산에서는 멀티스레딩이 무력화되는 구조적 한계가 있었습니다. 마치 여러 명이 일할 수 있는데도 한 명만 일하도록 강제하는 것과 같죠!

2. 테스트 환경 및 설치 준비 ⚙️

환경 설정

  • Python 버전 관리: pyenv 사용

설치 과정

# 3.14t-dev 버전 설치
pyenv install 3.14t-dev
pyenv global 3.14t-dev

비교용으로 3.11 버전도 함께 설치:

pyenv install 3.11.9
pyenv local 3.11.9

3. 테스트: CPU 사용률과 실행시간 비교

3.1 테스트 코드

먼저 동일한 CPU 바운드 작업을 여러 스레드로 나누어 실행하는 코드를 실행했습니다. 테스트 코드는 각 스레드가 math.sqrt()를 반복 수행하는 연산을 포함합니다.

pip install psutil # 라이브러리 설치 필요
import threading, time, math, psutil, os

def heavy_cpu_task():
    total = 0
    for i in range(100_000_000):
        total += math.sqrt(i)

def monitor():
    proc = psutil.Process(os.getpid())
    for _ in range(5):
        print(f"[{time.strftime('%H:%M:%S')}] CPU: {proc.cpu_percent(interval=1)}% / Threads: {proc.num_threads()}")

if __name__ == "__main__":
    # 모니터링 스레드 실행
    monitor_thread = threading.Thread(target=monitor)
    monitor_thread.start()

    # 메인 작업 스레드들 실행
    threads = [threading.Thread(target=heavy_cpu_task) for _ in range(4)]
    start = time.perf_counter()
    [t.start() for t in threads]
    [t.join() for t in threads]
    monitor_thread.join()

    print("총 소요 시간:", time.perf_counter() - start)

3.2 테스트 결과

  • Python 3.11 (GIL 있음):

    • CPU 사용률: 100~120% 수준
    • Thread count: 4
    • 하나의 코어만 집중적으로 사용되지만 같은 코어를 사용하지는 않음
    • 테스트 결과 4개의 cpu가 약 25% 점유 확인
    • 실행 시간: 약 11초 ⏱️
  • Python 3.14t-dev (GIL 제거):

    • CPU 사용률: 300~400%까지 상승
    • Thread count: 4
    • 여러 코어가 동시에 가동됨
    • 테스트 시에 4개의 cpu가 100% 점유 확인
    • 실행 시간: 약 5초 ⚡
python-3.11.9-test python-3.14t-test

간단하게 테스트 했지만 cpu 사용률과 실행 시간에 차이가 나는 것을 알 수 있었고, GIL이 제거되면서 진짜 병렬 처리가 가능해진 것을 직접 확인할 수 있었습니다.

3.3 추가적인 테스트

GIL이 제거된 Python 3.14t-dev 버전에서 스레드 수를 늘려가며 추가 테스트를 진행했습니다. 테스트 도중 CPU 사용량을 관찰한 결과, 실행 중인 스레드 수에 비례하여 CPU 사용률이 함께 증가하는 것을 확인할 수 있었습니다. 이는 GIL이 제거된 환경에서는 각 스레드가 병렬로 실행되며 실제로 여러 CPU 코어를 동시에 활용하고 있다는 것을 의미합니다.

참고로 테스트에 사용된 시스템은 총 10개의 CPU 코어를 가진 환경이었습니다. Python 3.14t-dev(GIL 제거 버전)에서 스레드 수를 점차 늘려가자 CPU 사용률도 함께 증가했으며, 최대 약 **1000%**까지 도달하는 것을 확인할 수 있었습니다. 이는 스레드 수가 많아질수록 실제로 여러 코어가 동시에 작업을 수행했다는 점을 뒷받침합니다.

반면, Python 3.11(GIL 존재)에서는 스레드 수와 무관하게 CPU 사용률이 최대 약 100% 수준에서 제한되었습니다. 이는 GIL로 인해 여러 스레드가 존재하더라도 한 번에 하나의 스레드만 실행되기 때문에, 멀티코어의 이점을 살릴 수 없다는 것을 보여줍니다.

3.3.1 3.11 thread에 따른 cpu 사용량

python-thead-4-311 python-thead-8-311 python-thead-20-311
3.3.2 3.14t thread에 따른 cpu 사용량
python-thead-4-314 python-thead-8-314 python-thead-20-314

4. 정리

항목3.11 (GIL 있음)3.14t-dev (GIL 제거)
병렬 처리불가능 (컨텍스트 스위칭만 발생)가능 (실제 멀티코어 병렬 실행)
CPU 사용률최대 약 100%스레드 수에 따라 최대 약 1000% 도달
실행 시간느림 (예: 약 11초)빠름 (예: 약 5초)
CPU 코어 활용 방식1개 코어를 순차적으로 스케줄링여러 코어를 동시에 사용
스레드 확장에 따른 성능개선 없음개선 있음

5. 나의 생각

이번 테스트는 단순한 코드 실행을 넘어서, CPU 사용률을 직접 관측하며 Python 내부에서 일어나는 일들을 조금 더 깊이 이해할 수 있는 기회였습니다. 특히 Python 3.14t-dev에서 GIL이 제거되면서 멀티스레딩이 실제로 병렬 처리되는 모습을 눈으로 확인한 순간은 꽤 흥미로웠습니다.

다만 멀티스레딩이 항상 더 좋은 선택은 아니라는 점도 느꼈습니다. 작업의 성격(예: I/O 바운드 vs CPU 바운드)에 따라 오히려 역효과가 날 수도 있기에, 적절한 사용 시점에 대한 추가적인 공부가 필요하다고 느꼈습니다. 이와 함께 이제는 멀티프로세싱에 대해서도 좀 더 깊이 파보고 싶어졌습니다.

또한 지금까지 GIL이 “CPU 하나만 사용한다”고 해서 같은 CPU만 계속 사용하는 줄 알았지만, 실제로는 여러 코어를 번갈아가며 사용하는 것이고 동시에 사용하지 못할 뿐이라는 것도 이번 테스트를 통해 명확히 이해하게 되었습니다.