파이썬 3.12에서 GIL 없는 병렬처리 도입 계획

최근 발표된 파이썬 3.11은 이전 버전 대비 10~60% 이상의 성능 향상을 보여 화제가 되었습니다. 뭐 파이썬이 원래 느려 먹어서 그정도는 쉽게 되는 거 아니냐는 사람들도 있는데, 파이썬3는 이미 파이썬 3.8부터 파이썬2보다 빠르다고 평가를 받아왔고, 계속해서 10% 가량의 성능을 개선해오다가 3.11에서 향상 폭이 커진 것입니다. 표준 파이썬 구현체의 비약적인 성능 개선을 위해 Faster CPypthon이라는 별도의 프로젝트가 기획되었고, 3.10부터 결과물이 나오고 있는 것입니다.

이 프로젝트의 3.12 버전에 대한 이 프로젝트의 목표 중 하나에 관심이 가는데, 그것은 진정한 멀티 스레드 병렬작업을 가능하게 하겠다는 것입니다. 현재까지 파이썬은 “전역 인터프리터 락”이라는 것을 사용하여 프로세스 내의 여러 스레드들이 실제로는 동시에 돌아가지 않고 각 스레드들이 번갈아가며 “한 번에 하나씩만” 실행되는 형태로 작동합니다. 그래서 스레드를 사용해서 동시에 작업을 실행하더라도, 한쪽 작업이 I/O 등 CPU를 사용하지 않는 일을 하지 않는 이상 실행 시간이 단축되지 않습니다.

그래서 프로세스내 전역 상태를 스레드 안전하게 만들고, 프로세스 내에서 여러 개의 서브 인터프리터가 동시에 실행되는 형태로 실제로 동시에 여러 코드가 실행되는 형태로 구현하겠다는 아이디어가 채택되었습니다. (PEP 684) 그리고 이 서브 인터프리터를 파이썬 프로세스 내에서 생성할 수 있게 하여(PEP 554) 이것으로 다중 스레드를 대체하는 것입니다.

실제로 ‘멀티 인터프리터’ 개념은 파이썬 초기(1.5)부터 존재했었습니다. 그러나 한 프로세스 내의 각각의 인터프린터들은 너무 많은 전역 상태를 공유했기 때문에, 동시에 작동할 때 발생하는 문제가 많았죠. 전통적인 동기화 수단들을 사용하여 GIL을 없애보려는 시도도 있었으나 전체적인 성능이 너무 저하되거나, 코드를 유지보수하기가 너무 까다로워지는 등의 이유로 중단되거나 했습니다. PEP684는 각각의 인터프리터를 “충분히” 격리하고 GIL을 각각의 인터프리터 내부로 옮기는 것에 관한 내용입니다. 그렇게 하면 하나의 인터프리터는 여전히 GIL의 영향을 받지만, 서로 다른 인터프리터는 영향을 받지 않으면서 실제로 동시에 CPU를 점유하여도 문제가 생기지 않게 하겠다는 것이죠.

PEP 554는 멀티인터프리터 혹은 서브인터프리터를 프로세스에서 직접 생성하고 사용하는 인터페이스를 만드는 것입니다. interpreters 라는 새로운 모듈이 추가되고 이 모듈에서 서브 인터프리터 관련한 기능을 제공합니다. 그리고 각각의 인터프리터는 채널이라는 수단을 통해서 마치 스레드 간에 큐를 사용하여 데이터 교환을 하는 것과 비슷한 방식으로 데이터를 교환합니다. PEP 554에서는 None, int, str, bytes 와 같은 단순한 타입에 대해서 우선적으로 지원하고 이후 교환 가능한 데이터 타입을 확대하겠다는 계획입니다.

import interpreters
import textwrap as tw
from threaing import Thread

interp = interpreters.create()
recv, send = interpreters.create_channel()

def run():
  interp.run(tw.dedent("""
    reader.recv()
    print("during")
    """),
    shared=dict(reader=r,))
  )

t = threading.Thread(target=run)
print('before')
t.start()
print('after')
s.send(b'')

커뮤니티 내에서도 GIL을 서브인터프리터로 옮기는 것에 대해서 많은 논의가 있는 것 같습니다. GIL을 서브인터프리터 내부로 넣는 것은 소잡는데 엑셀 팡션 쓰는 것 아니냐, 아직 표준라이브러리에 넣기에는 시기상조 아니냐, 하위 호환성은 어떡하냐 등등..

개인적으로는 어찌됐든 시기의 문제라고는 생각합니다. CPU의 코어 하나의 성능이 무한정 빨라질 수 없는 것은 자명하고, 컴퓨터 산업 자체가 멀티코어 기반으로 성능을 뽑아내는 쪽으로 발전해가고 다른 언어들도 그러한 방향을 지향하고 있는데 파이썬만 끝까지 “아 우리는 GIL.. 데헷 🙂 ” 이러고만은 있을 수 없으니까요. 물론 서브 인터프리터가 3.12에 실제로 포함될지는 모르는 일입니다. 이 내용은 아직까지 이 팀의 ‘목표’이니까요. 그리고 다른 목표들도 아직 갈길이 멀어 보입니다.

어쨌든 이런 논의가 그저 논의에만 그치지 않고 액션으로 착수됐다는 점은 상당히 고무적입니다. 그리고 3.12의 계획을 보면 어쩌면 3.11에서 보여준 드라마틱한 향상의 수준에 버금가거나 그 보다 더 큰 효과를 기대해도 좋지 않을까 하는 부분들이 있어서, 3.12의 진행도 관심을 가지고 지켜봐야겠습니다.

Read more

워드프레스에서 고스트로 이전

워드프레스에서 고스트로 이전

이 글을 쓰면서도 믿기 힘든 사실인데, 블로그라는 걸 처음 시작한지가 20년이 되었습니다. 이글루스에서 처음 시작했다가, SK컴즈가 인수한다고 발표함과 동시에 워드프레스로 플랫폼을 옮겼죠. 워드프레스오 옮긴 이후에는 호스팅 환경을 이리 저리 옮기긴 했지만 거의 18년 가까이 워드프레스를 사용해온 것 같습니다. 그 동안 워드프레스는 블로깅 툴에서 명실상부한 범용CMS로 발전했습니다. 사실 웬만한 홈페이지들은 이제

By sooop
띄어쓰기에 대한 생각

띄어쓰기에 대한 생각

업무 메일을 쓸 때 가장 많이 쓰는 말 중에 하나가 메일 말미에 ‘업무에 참고 부탁 드립니다.‘인데요, 어느 날부터 아웃룩에서 이 ‘부탁 드립니다’가 틀렸다고 맞춤법 지적을 하기 시작했습니다. 맞는 말은 ‘부탁드립니다’라고 붙여 쓰는 거라고. 사실 아래아한글 시절부터 이전의 MS워드까지, 워드프로세서들의 한국어 맞춤법 검사 실력은 거의 있으나 마나 한

By sooop

구글 포토에서 아이클라우드로 탈출한 후기

한 때 구글 포토가 백업 용량을 무제한으로 제공해 주겠다고해서, 구글 포토를 사용해서 사진을 백업해왔습니다. 물론 이 이야기의 결말은 저나 이 글을 읽고 있는 여러분이나 모두 알고 있습니다. 사실 AI에게 학습 시킬 이미지 데이터를 모으기 위한 것일 뿐이라거나 하는 이야기는 그 당시에도 있었습니다만, 에이 그래도 구글인데 용량은 넉넉하게 주겠지…하는 순진한

By sooop

Julia의 함수 사용팁

연산자의 함수적 표기 Julia의 연산자는 기본적으로 함수이며, 함수 호출 표기와 같은 방식으로 호출하는 것이 가능합니다. 또한 그 자체로 함수이기 때문에 filter(), map() 과 같이 함수를 인자로 받는 함수에도 연산자를 그대로 적용하는 것이 가능합니다. 특히 + 연산자는 sum() 함수와 같이 여러 인자를 받아 인자들의 합을 구할 수 있습니다. 2 + 3 # = 5 +(2,

By sooop