728x90

https://peps.python.org/pep-0703/

[PEP 703 โ€“ Making the Global Interpreter Lock Optional in CPython | peps.python.org

In CPython, the global interpreter lock protects against corruption of internal interpreter states when multiple threads concurrently access or modify Python objects. For example, if multiple threads concurrently modify the same list, the GIL ensures that

peps.python.org](https://peps.python.org/pep-0703/)

PEP 703 โ€“ CPython์—์„œ ์ „์—ญ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋ฝ(GIL)

  • Sam Gross
  • ลukasz Langa
  • Discourse thread

์ดˆ์•ˆ

  • 2023๋…„ 1์›” 9์ผ
  • Python ๋ฒ„์ „ 3.13
  • 2023๋…„ 1์›” 9์ผ๋ถ€ํ„ฐ 2023๋…„ 5์›” 4์ผ๊นŒ์ง€

Abstract

CPython์˜ ์ „์—ญ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋ฝ(GIL)์€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— Python ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค. GIL์€ Python์—์„œ ๋ฉ€ํ‹ฐ์ฝ”์–ด CPU๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ๋ฐฉํ•ดํ•ฉ๋‹ˆ๋‹ค. ์ด PEP์€ CPython์— ๋นŒ๋“œ ๊ตฌ์„ฑ(--disable-gil)์„ ์ถ”๊ฐ€ํ•˜์—ฌ ์ „์—ญ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋ฝ ์—†์ด Python ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์ธํ„ฐํ”„๋ฆฌํ„ฐ์˜ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์„ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•œ ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

๋™๊ธฐ

GIL์€ ๋™์‹œ์„ฑ์— ๋Œ€ํ•œ ์ฃผ์š” ์žฅ์• ๋ฌผ์ž…๋‹ˆ๋‹ค. ๊ณผํ•™ ๊ณ„์‚ฐ ์ž‘์—…์—์„œ๋Š” ์ด๋Ÿฌํ•œ ๋™์‹œ์„ฑ์˜ ๋ถ€์žฌ๊ฐ€ Python ์ฝ”๋“œ ์‹คํ–‰ ์†๋„๋ณด๋‹ค ๋” ํฐ ๋ฌธ์ œ๊ฐ€ ๋  ๋•Œ๊ฐ€ ๋งŽ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ๋Œ€๋ถ€๋ถ„์˜ ํ”„๋กœ์„ธ์„œ ์‚ฌ์ดํด์€ ์ตœ์ ํ™”๋œ CPU ๋˜๋Š” GPU ์ปค๋„์—์„œ ์†Œ๋น„๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. GIL์€ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ Python ์ฝ”๋“œ๋ฅผ ํ˜ธ์ถœํ•  ๊ฒฝ์šฐ ์ง„ํ–‰์„ ๋ฐฉํ•ดํ•  ์ˆ˜ ์žˆ๋Š” ์ „์—ญ ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ CPython์—์„œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ๋ฐฉ๋ฒ•์ด ์žˆ์ง€๋งŒ, ์ด๋Ÿฌํ•œ ๊ธฐ์ˆ ์€ ์ค‘์š”ํ•œ ์ œํ•œ ์‚ฌํ•ญ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค(๋Œ€์•ˆ ์ฐธ์กฐ).

์ด ์„น์…˜์—์„œ๋Š” ๊ณผํ•™ ๊ณ„์‚ฐ์„ ์œ„ํ•œ GIL์˜ ์˜ํ–ฅ์— ์ดˆ์ ์„ ๋งž์ถ”๊ณ  ์žˆ์œผ๋ฉฐ, ํŠนํžˆ ์ธ๊ณต ์ง€๋Šฅ/๋จธ์‹  ๋Ÿฌ๋‹ ์ž‘์—…์— ๋Œ€ํ•œ ์˜ํ–ฅ์„ ๋‹ค๋ฃจ๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ž‘์„ฑ์ž๋Š” ์ด ๋ถ„์•ผ์—์„œ ๊ฐ€์žฅ ๋งŽ์€ ๊ฒฝํ—˜์„ ๊ฐ€์ง€๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ GIL์€ Python์˜ ๋‹ค๋ฅธ ์‚ฌ์šฉ์ž๋“ค์—๊ฒŒ๋„ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

GIL๋กœ ์ธํ•ด ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๊ฐ€ ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค.

์‹ ๊ฒฝ๋ง ๊ธฐ๋ฐ˜์˜ AI ๋ชจ๋ธ์€ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ์˜ ๋‹ค์–‘ํ•œ ๊ธฐํšŒ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๊ฐœ๋ณ„ ์ž‘์—…์€ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ณ‘๋ ฌํ™”๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ("intra-operator"), ์—ฌ๋Ÿฌ ์ž‘์—…์„ ๋™์‹œ์— ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ("inter-operator"), ์š”์ฒญ(์—ฌ๋Ÿฌ ์ž‘์—…์„ ํฌํ•จ)์€ ๋ณ‘๋ ฌํ™”๋  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. ํšจ์œจ์ ์ธ ์‹คํ–‰์„ ์œ„ํ•ด์„œ๋Š” ๋‹ค์–‘ํ•œ ์œ ํ˜•์˜ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ํ™œ์šฉํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค [1].

GIL์€ Python์—์„œ inter-operator ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ๋ฐ ์ผ๋ถ€ ํ˜•ํƒœ์˜ ์š”์ฒญ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ํšจ์œจ์ ์œผ๋กœ ํ‘œํ˜„ํ•˜๊ธฐ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด์—์„œ๋Š” ์‹œ์Šคํ…œ์ด ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ ๊ฒฝ๋ง์˜ ๊ฐ ๋ถ€๋ถ„์„ ๋ณ„๋„์˜ CPU ์ฝ”์–ด์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, GIL๋กœ ์ธํ•ด Python์—์„œ๋Š” ์ด๊ฒƒ์ด ๋น„ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค. ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์ง€์—ฐ ์‹œ๊ฐ„์— ๋ฏผ๊ฐํ•œ ์ถ”๋ก  ์ž‘์—…์€ ์ข…์ข… ์—ฌ๋Ÿฌ ์š”์ฒญ์— ๊ฑธ์ณ ๋ณ‘๋ ฌํ™”๋ฅผ ์œ„ํ•ด ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, Python์—์„œ๋Š” ๋™์ผํ•œ ํ™•์žฅ์„ฑ ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ๋งˆ์ฃผํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.

GIL์ด Python์—์„œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ํ™œ์šฉํ•˜๋Š” ๋ฐ ์–ด๋ ค์›€์„ ์ผ์œผํ‚ค๋Š” ๋ฌธ์ œ๋Š” ๊ฐ•ํ™” ํ•™์Šต์—์„œ ์ž์ฃผ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. NetHack Learning Environment์˜ ์ €์ž์ด์ž Inflection AI์˜ Technical Staff ๋ฉค๋ฒ„์ธ Heinrich Kuttler๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งํ•ฉ๋‹ˆ๋‹ค:

"DotA 2, StarCraft, NetHack ๋“ฑ์˜ ์ตœ๊ทผ ๊ฐ•ํ™” ํ•™์Šต์˜ ํš๊ธฐ์ ์ธ ๋ฐœ์ „์€ ๋น„๋™๊ธฐ์ ์ธ ์•กํ„ฐ-ํฌ๋ฆฌํ‹ฑ ๋ฐฉ๋ฒ•์„ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ‘๋ ฌ๋กœ ์—ฌ๋Ÿฌ ํ™˜๊ฒฝ(์‹œ๋ฎฌ๋ ˆ์ด์…˜ ๊ฒŒ์ž„)์„ ์‹คํ–‰ํ•˜๋Š” ๋ฐ ์˜์กดํ•ฉ๋‹ˆ๋‹ค. Python์˜ ๋‹จ์ˆœํ•œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ๊ตฌํ˜„์€ GIL ๊ฒฝํ•ฉ ๋•Œ๋ฌธ์— ๋ช‡ ๊ฐœ ์ด์ƒ์˜ ๋ณ‘๋ ฌ ํ™˜๊ฒฝ์—์„œ ํ™•์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ๋‚˜ UNIX ์†Œ์ผ“์„ ํ†ตํ•ด ํ†ต์‹ ํ•˜๋Š” ๋‹ค์ค‘ ํ”„๋กœ์„ธ์‹ฑ์€ ๋งŽ์€ ๋ณต์žก์„ฑ์„ ๋™๋ฐ˜ํ•˜๋ฉฐ, CUDA๋ฅผ ๋‹ค๋ฅธ ์›Œ์ปค์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์‚ฌ์‹ค์ƒ ๋ถˆ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“ค์–ด ์„ค๊ณ„ ๊ณต๊ฐ„์„ ์‹ฌ๊ฐํ•˜๊ฒŒ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค."

GIL(Globel Interpreter Lock)๋กœ ์ธํ•œ ํŒŒ์ด์ฌ ์ฝ”๋“œ์˜ ์ ‘๊ทผ์„ฑ ์ €ํ•˜

๋งŽ์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ DeepMind์—์„œ Python GIL๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์ œ์— ์ง๋ฉดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ๋ณดํ†ต ํ•˜๋‚˜์˜ ํ”„๋กœ์„ธ์Šค์—์„œ 50-100๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ์‹คํ–‰ํ•˜๊ณ  ์‹ถ์–ดํ•˜์ง€๋งŒ, ๋•Œ๋กœ๋Š” 10๊ฐœ ์ดํ•˜์˜ ์Šค๋ ˆ๋“œ๋ผ๋„ GIL์ด ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ์ผ์œผํ‚ต๋‹ˆ๋‹ค. ์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ๋•Œ๋กœ๋Š” ์„œ๋ธŒํ”„๋กœ์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜์ง€๋งŒ, ๋งŽ์€ ๊ฒฝ์šฐ์—๋Š” ํ”„๋กœ์„ธ์Šค๊ฐ„ ํ†ต์‹ ์ด ๋„ˆ๋ฌด ํฐ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋ฉ๋‹ˆ๋‹ค. GIL๊ณผ ๊ด€๋ จ๋œ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์šฐ๋ฆฌ๋Š” ๋ณดํ†ต Python ์ฝ”๋“œ ๋ฒ ์ด์Šค์˜ ํฐ ๋ถ€๋ถ„์„ C++๋กœ ๋ณ€ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์—ฐ๊ตฌ์›๋“ค์—๊ฒŒ ์ฝ”๋“œ ์ ‘๊ทผ์„ฑ์„ ๋–จ์–ด๋œจ๋ฆฌ๋Š” ๋ถ€์ž‘์šฉ์„ ์ผ์œผํ‚ต๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ํ•˜๋“œ์›จ์–ด ์žฅ์น˜์™€์˜ ์ธํ„ฐํŽ˜์ด์Šค๋ฅผ ํฌํ•จํ•˜๋Š” ํ”„๋กœ์ ํŠธ๋“ค์€ ์œ ์‚ฌํ•œ ๋„์ „์„ ์ง๋ฉดํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. Dose-3D ํ”„๋กœ์ ํŠธ๋Š” ์ •ํ™•ํ•œ ์šฉ๋Ÿ‰ ๊ณ„ํš์œผ๋กœ ์•” ๋ฐฉ์‚ฌ์„  ์น˜๋ฃŒ๋ฅผ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉํ‘œ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ๋Š” ์‚ฌ๋žŒ์˜ ์กฐ์ง์„ ๋Œ€์‹ ํ•  ์ˆ˜ ์žˆ๋Š” ์˜๋ฃŒ ์œ ์‚ฌ์ฒด(medical phantom)์™€ ํ•จ๊ป˜ Python์œผ๋กœ ์ž‘์„ฑ๋œ ์„œ๋ฒ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ์ปค์Šคํ…€ ํ•˜๋“œ์›จ์–ด๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Dose-3D ํ”„๋กœ์ ํŠธ์˜ ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ์‹œ์Šคํ…œ์˜ ์ฃผ์š” ์†Œํ”„ํŠธ์›จ์–ด ์•„ํ‚คํ…ํŠธ์ธ Paweล‚ Jurgielewicz์€ GIL์— ์˜ํ•ด ์ œ๊ธฐ๋˜๋Š” ํ™•์žฅ ๋ฌธ์ œ์™€ GIL์ด ์—†๋Š” Python์˜ ํฌํฌ๋ฅผ ์‚ฌ์šฉํ•จ์œผ๋กœ์จ ํ”„๋กœ์ ํŠธ๋ฅผ ๋‹จ์ˆœํ™”ํ•œ ๊ฒฝํ—˜์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

Dose-3D ํ”„๋กœ์ ํŠธ์—์„œ ์ฃผ์š”ํ•œ ๋„์ „์€ ํ•˜๋“œ์›จ์–ด ์žฅ์น˜์™€ ์•ˆ์ •์ ์ด๊ณ  ๋ณต์žกํ•œ ๋™์‹œ ํ†ต์‹  ๋งํฌ๋ฅผ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, 1 Gbit/s UDP/IP ์—ฐ๊ฒฐ์„ ์ตœ๋Œ€ํ•œ ํ™œ์šฉํ•ด์•ผ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๋Š” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ multiprocessing ํŒจํ‚ค์ง€๋ฅผ ์‚ฌ์šฉํ•ด ์‹œ์ž‘ํ–ˆ์ง€๋งŒ, ์–ด๋Š ์ˆœ๊ฐ„์—๋Š” ๋ฐ์ดํ„ฐ ์ „์†ก์ด ๋ฐ์ดํ„ฐ ์ฒ˜๋ฆฌ ๋‹จ๊ณ„๋ณด๋‹ค CPU ์‹œ๊ฐ„์˜ ๋Œ€๋ถ€๋ถ„์„ ์†Œ๋ชจํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. GIL์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ CPython์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ๊ตฌํ˜„์€ ๋ง‰๋‹ค๋ฅธ ๊ธธ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์šฐ๋ฆฌ๊ฐ€ "nogil"์ด๋ผ๋Š” Python ํฌํฌ์— ๋Œ€ํ•ด ์•Œ๊ฒŒ ๋œ ํ›„์—๋Š” ๋‹จ ํ•œ ๋ช…์˜ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ฝ”๋“œ๋ฒ ์ด์Šค๋ฅผ ์ด ํฌํฌ๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์กฐ์ •ํ•˜๋Š” ๋ฐ์— ์ ˆ๋ฐ˜ ์ •๋„์˜ ์—…๋ฌด ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ๊ณ , ๊ฒฐ๊ณผ๋Š” ๋†€๋ผ์› ์Šต๋‹ˆ๋‹ค. ์ด์ œ ์šฐ๋ฆฌ๋Š” ๋ฐ์ดํ„ฐ ๊ตํ™˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ธ๋ฐ€ํ•˜๊ฒŒ ์กฐ์ •ํ•˜๋Š” ๋Œ€์‹  ๋ฐ์ดํ„ฐ ์ˆ˜์ง‘ ์‹œ์Šคํ…œ ๊ฐœ๋ฐœ์— ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

CellProfiler์˜ ์ €์ž์ด์ž Prescient Design ๋ฐ Genentech์˜ ์Šคํƒœํ”„ ์—”์ง€๋‹ˆ์–ด์ธ Allen Goodman์€ GIL๋กœ ์ธํ•ด ์ƒ๋ฌผํ•™์  ๋ฐฉ๋ฒ• ์—ฐ๊ตฌ๊ฐ€ ํŒŒ์ด์ฌ์—์„œ ๋” ์–ด๋ ค์›Œ์ง„๋‹ค๊ณ  ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

Python์˜ ๊ธ€๋กœ๋ฒŒ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ž ๊ธˆ(GIL)์€ ์ƒ๋ฌผํ•™์  ๋ฐฉ๋ฒ• ์—ฐ๊ตฌ ์ „๋ฐ˜์— ๊ฑธ์ณ ๋นˆ๋ฒˆํ•œ ์ขŒ์ ˆ์˜ ์›์ธ์ด ๋ฉ๋‹ˆ๋‹ค.

์ €๋Š” ํ˜„์žฌ์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ์ƒํ™ฉ์„ ๋” ์ž˜ ์ดํ•ดํ•˜๊ธฐ ์œ„ํ•ด HMMER, ์—ฌ๋Ÿฌ ์„œ์—ด ์ •๋ ฌ์— ์‚ฌ์šฉ๋˜๋Š” ํ‘œ์ค€ ๋ฐฉ๋ฒ•์˜ ์ผ๋ถ€๋ฅผ ์žฌ๊ตฌํ˜„ํ•ด ๋ณด์•˜์Šต๋‹ˆ๋‹ค. ์ด ๋ฐฉ๋ฒ•์€ ๋‹จ์ผ ์Šค๋ ˆ๋“œ ์„ฑ๋Šฅ(์ ์ˆ˜ ๋งค๊ธฐ๊ธฐ)๊ณผ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ์„ฑ๋Šฅ(์„œ์—ด ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ๊ฒ€์ƒ‰)์„ ๋ชจ๋‘ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค. GIL์€ 8๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋งŒ ์‚ฌ์šฉํ•  ๋•Œ์—๋„ ๋ณ‘๋ชฉ ํ˜„์ƒ์ด ๋ฐœ์ƒํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ์ธ๊ธฐ ์žˆ๋Š” ๊ตฌํ˜„์€ ํ”„๋กœ์„ธ์Šค ๋‹น 64๊ฐœ ์ด์ƒ ๋˜๋Š” 128๊ฐœ์˜ ์Šค๋ ˆ๋“œ์— ์˜์กดํ•ฉ๋‹ˆ๋‹ค. ์ €๋Š” ์„œ๋ธŒํ”„๋กœ์„ธ์Šค๋กœ ์ด๋™ํ•ด ๋ณด์•˜์ง€๋งŒ, IPC cost ๋•Œ๋ฌธ์— ๋ง‰ํ˜”์Šต๋‹ˆ๋‹ค. HMMER๋Š” ์ƒ๋Œ€์ ์œผ๋กœ ๊ธฐ์ดˆ์ ์ธ ์ƒ๋ฌผ์ •๋ณดํ•™ ๋ฐฉ๋ฒ•์ด๋ฉฐ, ์ตœ์‹  ๋ฐฉ๋ฒ•๋“ค์€ ํ›จ์”ฌ ๋” ํฐ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ์š”๊ตฌ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฐฉ๋ฒ• ์—ฐ๊ตฌ์ž๋“ค์€ ์‚ฌ์šฉํ•˜๊ธฐ ์‰ฌ์šฐ๋ฉฐ, Python ์ƒํƒœ๊ณ„์™€ "์‚ฌ๋žŒ๋“ค์ด ์•„๋Š” ์–ธ์–ด"๋ผ๋Š” ์ด์œ ๋กœ Python์„ ์‚ฌ์šฉํ•˜๊ณ ์ž ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ Python์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ์ƒํ™ฉ์ด ๊ฐœ์„ ๋˜์ง€ ์•Š๋Š” ํ•œ, C์™€ C++์€ ์ƒ๋ฌผํ•™์  ๋ฐฉ๋ฒ• ์—ฐ๊ตฌ ์ปค๋ฎค๋‹ˆํ‹ฐ์˜ ๊ณต์šฉ์–ด๋กœ ๋‚จ๊ฒŒ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

GIL์ด ํŒŒ์ด์ฌ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์„ฑ์— ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค.

GIL์€ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ์ œํ•œํ•˜๋Š” CPython์˜ ๊ตฌํ˜„ ์„ธ๋ถ€ ์‚ฌํ•ญ์ด๊ธฐ ๋•Œ๋ฌธ์— ์‚ฌ์šฉ์„ฑ ๋ฌธ์ œ๋กœ ๊ฐ„์ฃผํ•˜๊ธฐ์—๋Š” ๋‚ฏ์„ค๊ฒŒ ๋Š๊ปด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ž‘์„ฑ์ž๋“ค์€ ์ข…์ข… ์„ฑ๋Šฅ์— ํฐ ๊ด€์‹ฌ์„ ๊ฐ€์ง€๋ฉฐ, GIL์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•œ API๋ฅผ ์„ค๊ณ„ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํšŒํ”ผ ๋ฐฉ๋ฒ•์€ ๋ณด๋‹ค ์–ด๋ ค์šด ์‚ฌ์šฉ์„ฑ์„ ๊ฐ€์ง„ API๋กœ ์ด์–ด์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์ ์œผ๋กœ, ์ด๋Ÿฌํ•œ API์˜ ์‚ฌ์šฉ์ž๋“ค์€ ์„ฑ๋Šฅ ๋ฌธ์ œ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ ์‚ฌ์šฉ์„ฑ ๋ฌธ์ œ๋กœ์„œ GIL์„ ๊ฒฝํ—˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์˜ˆ๋ฅผ ๋“ค์–ด, PyTorch๋Š” ๋ฐ์ดํ„ฐ ์ž…๋ ฅ ํŒŒ์ดํ”„๋ผ์ธ์„ ๊ตฌ์ถ•ํ•˜๊ธฐ ์œ„ํ•œ multiprocessing ๊ธฐ๋ฐ˜ API์ธ DataLoader๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์ด API๋Š” Linux์—์„œ fork()๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์ด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ spawn()๋ณด๋‹ค ๋น ๋ฅด๊ณ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋œ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” ์‚ฌ์šฉ์ž์—๊ฒŒ ์ถ”๊ฐ€์ ์ธ ๋„์ „์„ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. GPU์— ์•ก์„ธ์Šคํ•œ ํ›„ DataLoader๋ฅผ ์ƒ์„ฑํ•˜๋ฉด ํ˜ผ๋ž€์Šค๋Ÿฌ์šด CUDA ์˜ค๋ฅ˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. DataLoader ์ž‘์—…์ž ๋‚ด์—์„œ GPU์— ์•ก์„ธ์Šคํ•˜๋ฉด CUDA ์ปจํ…์ŠคํŠธ๋ฅผ ํ”„๋กœ์„ธ์Šค๊ฐ€ ๊ณต์œ ํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ ๋ถ€์กฑ ์˜ค๋ฅ˜๊ฐ€ ๋น ๋ฅด๊ฒŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

scikit-learn ๊ฐœ๋ฐœ์ž์ด์ž Inria์˜ ์†Œํ”„ํŠธ์›จ์–ด ์—”์ง€๋‹ˆ์–ด์ธ Olivier Grisel์€ scikit-learn ๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์—์„œ GIL์„ ์šฐํšŒํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ์ด ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์„ ๋” ๋ณต์žกํ•˜๊ณ  ํ˜ผ๋ž€์Šค๋Ÿฝ๊ฒŒ ๋งŒ๋“ ๋‹ค๊ณ  ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์—ฌ๋Ÿฌ ํ•ด๊ฐ€ ์ง€๋‚จ์— ๋”ฐ๋ผ, scikit-learn ๊ฐœ๋ฐœ์ž๋“ค์€ joblib, loky, Ralf Gommers, Quansight Labs์˜ ๊ณต๋™ ๋””๋ ‰ํ„ฐ์ด์ž NumPy ๋ฐ SciPy ์œ ์ง€ ๊ด€๋ฆฌ์ž๋Š” GIL์ด NumPy ๋ฐ ์ˆซ์ž ๊ณ„์‚ฐ์šฉ Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ์–ด๋–ค ์˜ํ–ฅ์„ ๋ฏธ์น˜๋Š”์ง€์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

joblib

GIL์ด NumPy์™€ Numeric Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ์‚ฌ์šฉ์ž ๊ฒฝํ—˜์— ๋ฏธ์น˜๋Š” ์˜ํ–ฅ

NumPy์™€ NumPy๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ํŒจํ‚ค์ง€ ์Šคํƒ์—์„œ์˜ ์ฃผ์š” ๋ฌธ์ œ๋Š” NumPy๊ฐ€ ์—ฌ์ „ํžˆ (๋Œ€๋ถ€๋ถ„) ๋‹จ์ผ ์Šค๋ ˆ๋“œ๋กœ ๊ตฌ์„ฑ๋˜์–ด ์žˆ๋‹ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์‚ฌ์šฉ์ž ๊ฒฝํ—˜๊ณผ ์ด๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ํ”„๋กœ์ ํŠธ์˜ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์„ ํ˜•์„ฑํ•ด ์™”์Šต๋‹ˆ๋‹ค. NumPy๋Š” ๋‚ด๋ถ€ ๋ฃจํ”„์—์„œ GIL์„ ํ•ด์ œํ•˜์ง€๋งŒ ์ด๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. NumPy๋Š” ๋‹จ์ผ ์ปดํ“จํ„ฐ์˜ ๋ชจ๋“  CPU ์ฝ”์–ด๋ฅผ ํšจ๊ณผ์ ์œผ๋กœ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•œ ํ•ด๊ฒฐ์ฑ…์„ ์ œ๊ณตํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋Œ€์‹  Dask์™€ ๊ฐ™์€ ๋‹ค๋ฅธ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ ์†”๋ฃจ์…˜์— ์ด๋ฅผ ๋งก๊น๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฌํ•œ ์†”๋ฃจ์…˜๋“ค์€ ํšจ์œจ์ ์ด์ง€ ์•Š์œผ๋ฉฐ ์‚ฌ์šฉํ•˜๊ธฐ๋„ ๋” ์–ด๋ ต์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฐ ์–ด๋ ค์›€์€ ์ฃผ๋กœ ์‚ฌ์šฉ์ž๊ฐ€ ์‚ฌ์šฉํ•  ๋•Œ ์ถ”๊ฐ€์ ์ธ ์ถ”์ƒํ™”์™€ ๊ณ„์ธต์„ ๊ณ ๋ คํ•ด์•ผ ํ•˜๋Š” ๋ถ€๋ถ„์—์„œ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค.

๊ด€๋ จ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ

  • dask.array
  • numpy.ndarray
  • threadpoolctl

๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ์ œ์–ดํ•˜๊ธฐ ์œ„ํ•œ API ๋ฐ ๋””์ž์ธ ๊ฒฐ์ •์„ ์กฐ์ •ํ•˜๋Š” ์ž‘์—…์€ ์—ฌ์ „ํžˆ PyData ์ƒํƒœ๊ณ„ ์ „๋ฐ˜์—์„œ ๊ฐ€์žฅ ์–ด๋ ค์šด ๋ฌธ์ œ ์ค‘ ํ•˜๋‚˜์ž…๋‹ˆ๋‹ค. GIL์ด ์—†์—ˆ๋‹ค๋ฉด ์ด ์ž‘์—…์€ ํ›จ์”ฌ ๋‹ค๋ฅด๊ณ  (๋” ์ข‹๊ณ , ์‰ฌ์› ์„ ๊ฒƒ์ž…๋‹ˆ๋‹ค).

GPU ์ค‘์‹ฌ์˜ ์ž‘์—…์€ ๋ฉ€ํ‹ฐ์ฝ”์–ด ์ฒ˜๋ฆฌ๋ฅผ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค

๊ณ ์„ฑ๋Šฅ ์ปดํ“จํŒ…(HPC) ๋ฐ AI ์ž‘์—…์€ GPU๋ฅผ ์ค‘์‹ฌ์œผ๋กœ ๋งŽ์ด ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ๊ณ„์‚ฐ์„ GPU์—์„œ ์‹คํ–‰ํ•˜์ง€๋งŒ ํšจ์œจ์ ์ธ ๋ฉ€ํ‹ฐ์ฝ”์–ด CPU ์‹คํ–‰์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

PyTorch ํ•ต์‹ฌ ๊ฐœ๋ฐœ์ž์ด์ž FAIR (Meta AI)์˜ ์—ฐ๊ตฌ์›์ธ Zachary DeVito๋Š” GIL๋กœ ์ธํ•ด Python ์™ธ๋ถ€์—์„œ ๋Œ€๋ถ€๋ถ„์˜ ๊ณ„์‚ฐ์ด ์ˆ˜ํ–‰๋˜๋Š” ๊ฒฝ์šฐ์—๋„ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™•์žฅ์ด ๋น„ํšจ์œจ์ ์ด๋ผ๊ณ  ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

PyTorch์—์„œ๋Š” Python์„ ์‚ฌ์šฉํ•˜์—ฌ ๋Œ€๊ฐœ ~8๊ฐœ์˜ GPU์™€ ~64๊ฐœ์˜ CPU ์Šค๋ ˆ๋“œ๋ฅผ ์กฐ์ •ํ•˜๋ฉฐ, ๋Œ€๊ทœ๋ชจ ๋ชจ๋ธ์˜ ๊ฒฝ์šฐ 4k๊ฐœ์˜ GPU์™€ 32k๊ฐœ์˜ CPU ์Šค๋ ˆ๋“œ๊นŒ์ง€ ํ™•์žฅ๋ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ์ž‘์—…์€ Python ์™ธ๋ถ€์—์„œ ์ˆ˜ํ–‰๋˜์ง€๋งŒ GPU์˜ ์†๋„ ๋•Œ๋ฌธ์— Python์—์„œ์˜ ์กฐ์ •๋งŒ์œผ๋กœ๋„ ํ™•์žฅ์ด ์–ด๋ ต์Šต๋‹ˆ๋‹ค. GIL ๋•Œ๋ฌธ์— ํ•˜๋‚˜ ๋Œ€์‹  72๊ฐœ์˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ํ•„์š”ํ•œ ๊ฒฝ์šฐ๊ฐ€ ์ข…์ข… ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋กœ๊น…, ๋””๋ฒ„๊น… ๋ฐ ์„ฑ๋Šฅ ํŠœ๋‹์ด ์–ด๋ ค์›Œ์ง€๋ฉฐ ๊ฐœ๋ฐœ์ž์˜ ์ƒ์‚ฐ์„ฑ์ด ํฌ๊ฒŒ ์ €ํ•˜๋ฉ๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ๋Œ€์‹  ๋งŽ์€ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์€ ์ผ๋ฐ˜์ ์ธ ์ž‘์—…์„ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. Zachary DeVito๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋งํ•ฉ๋‹ˆ๋‹ค.

"์ง€๋‚œ ๋ช‡ ๋‹ฌ ๋™์•ˆ ์ค‘๋ณต ๊ณ„์‚ฐ์„ ์ค„์ด๋Š” ๋ฐ์ดํ„ฐ ๋กœ๋”, ๋ชจ๋ธ ์ฒดํฌํฌ์ธํŠธ๋ฅผ ๋น„๋™๊ธฐ๋กœ ์ž‘์„ฑํ•˜๋Š” ๊ฒƒ, ์ปดํŒŒ์ผ๋Ÿฌ ์ตœ์ ํ™”๋ฅผ ๋ณ‘๋ ฌํ™”ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ GIL ์ œ์•ฝ์„ ์–ด๋–ป๊ฒŒ ํ”ผํ• ์ง€์— ๋Œ€ํ•ด ์•Œ์•„๋ณด๋Š” ๋ฐ ์‹œ๊ฐ„์„ ์†Œ์š”ํ•œ ๊ฒƒ์€ ์‹ค์ œ๋กœ ๊ทธ ๋ฌธ์ œ ์ž์ฒด๋ฅผ ํ•ด๊ฒฐํ•˜๋Š” ๋ฐ๋ณด๋‹ค๋„ ํ•œ ์ฐจ์› ๋” ์˜ค๋žœ ์‹œ๊ฐ„์ด ๊ฑธ๋ ธ์Šต๋‹ˆ๋‹ค."

์‹ฌ์ง€์–ด GPU ์ค‘์‹ฌ์˜ ์ž‘์—…๋“ค๋„ CPU ์ง‘์•ฝ์ ์ธ ๋ถ€๋ถ„์ด ์ž์ฃผ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ์ปดํ“จํ„ฐ ๋น„์ „ ์ž‘์—…์€ ์ด๋ฏธ์ง€ ๋””์ฝ”๋”ฉ, ํฌ๋กญ ๋ฐ ๋ฆฌ์‚ฌ์ด์ง•๊ณผ ๊ฐ™์€ "์ „์ฒ˜๋ฆฌ" ๋‹จ๊ณ„๋ฅผ ์—ฌ๋Ÿฌ ๊ฐœ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž‘์—…์€ ์ผ๋ฐ˜์ ์œผ๋กœ CPU์—์„œ ์ˆ˜ํ–‰๋˜๋ฉฐ Pillow๋‚˜ Pillow-SIMD์™€ ๊ฐ™์€ Python ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. GPU๋ฅผ ๋ฐ์ดํ„ฐ๋กœ "๊ณต๊ธ‰"ํ•˜๊ธฐ ์œ„ํ•ด ๋ฐ์ดํ„ฐ ์ž…๋ ฅ ํŒŒ์ดํ”„๋ผ์ธ์„ ์—ฌ๋Ÿฌ CPU ์ฝ”์–ด์—์„œ ์‹คํ–‰ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

๊ฐœ๋ณ„ CPU ์ฝ”์–ด ๋Œ€๋น„ GPU ์„ฑ๋Šฅ์˜ ์ฆ๊ฐ€๋กœ ์ธํ•ด ๋ฉ€ํ‹ฐ์ฝ”์–ด ์„ฑ๋Šฅ์ด ๋” ์ค‘์š”ํ•ด์กŒ์Šต๋‹ˆ๋‹ค. GPU๋ฅผ ์™„์ „ํžˆ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํšจ์œจ์ ์ธ ์—ฌ๋Ÿฌ CPU ์ฝ”์–ด์˜ ์‚ฌ์šฉ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ํŠนํžˆ ๋‹ค์ค‘ GPU ์‹œ์Šคํ…œ์—์„œ๋Š” ๋”์šฑ ์–ด๋ ค์›Œ์กŒ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, NVIDIA์˜ DGX-A100์€ 8๊ฐœ์˜ GPU์™€ 2๊ฐœ์˜ 64์ฝ”์–ด CPU๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GPU๋ฅผ ๋ฐ์ดํ„ฐ๋กœ "๊ณต๊ธ‰"ํ•ฉ๋‹ˆ๋‹ค.

GIL๋กœ ์ธํ•ด Python AI ๋ชจ๋ธ ๋ฐฐํฌ๊ฐ€ ์–ด๋ ค์›Œ์ง‘๋‹ˆ๋‹ค

Python์€ ์‹ ๊ฒฝ๋ง ๊ธฐ๋ฐ˜ AI ๋ชจ๋ธ์„ ๊ฐœ๋ฐœํ•˜๋Š” ๋ฐ ๋„๋ฆฌ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. PyTorch์—์„œ ๋ชจ๋ธ์€ ์ž์ฃผ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ๋กœ ๋œ ์ฃผ๋กœ C++ ํ™˜๊ฒฝ์˜ ์ผ๋ถ€๋กœ ๋ฐฐํฌ๋ฉ๋‹ˆ๋‹ค. GIL๋กœ ์ธํ•ด ํšจ์œจ์ ์ธ ํ™•์žฅ์ด ๋ฐฉํ•ด๋˜์–ด Python์€ ์ข…์ข… ํšŒ์˜์ ์œผ๋กœ ์—ฌ๊ฒจ์ง‘๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ ๋Œ€๋ถ€๋ถ„์˜ ๊ณ„์‚ฐ์ด GIL์ด ํ•ด์ œ๋œ Python ์™ธ๋ถ€์—์„œ ์ˆ˜ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. torchdeploy ๋…ผ๋ฌธ์—์„œ๋Š” ์ด๋Ÿฌํ•œ ํ™•์žฅ ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ์—ฌ๋Ÿฌ ๋ชจ๋ธ ์•„ํ‚คํ…์ฒ˜์—์„œ ์‹คํ—˜์ ์œผ๋กœ ์ž…์ฆํ–ˆ์Šต๋‹ˆ๋‹ค.

PyTorch๋Š” GIL์„ ํ”ผํ•˜๊ฑฐ๋‚˜ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ์—ฌ๋Ÿฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์ œ๊ณตํ•˜์ง€๋งŒ ๋ชจ๋‘ ์ค‘์š”ํ•œ ์ œํ•œ ์‚ฌํ•ญ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, TorchScript๋Š” Python ์ข…์†์„ฑ ์—†์ด C++์—์„œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ชจ๋ธ์˜ ํ‘œํ˜„์„ ์บก์ฒ˜ํ•˜์ง€๋งŒ ์ œํ•œ๋œ Python ํ•˜์œ„ ์ง‘ํ•ฉ๋งŒ ์ง€์›ํ•˜๋ฉฐ ๋ชจ๋ธ์˜ ์ผ๋ถ€ ์ฝ”๋“œ๋ฅผ ๋‹ค์‹œ ์ž‘์„ฑํ•ด์•ผ ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. torch::deploy API๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ๋™์ผํ•œ ํ”„๋กœ์„ธ์Šค์—์„œ ๊ฐ๊ฐ ๊ณ ์œ ํ•œ GIL์„ ๊ฐ€์ง„ ์—ฌ๋Ÿฌ Python ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(PEP 684๊ณผ ์œ ์‚ฌ). ๊ทธ๋Ÿฌ๋‚˜ torch::deploy๋Š” C-API ํ™•์žฅ์„ ์‚ฌ์šฉํ•˜๋Š” Python ๋ชจ๋“ˆ์— ๋Œ€ํ•œ ์ง€์›์ด ์ œํ•œ์ ์ž…๋‹ˆ๋‹ค.

๋™๊ธฐ

๋งŽ์€ ๊ณผํ•™ ๋ฐ ์ˆ˜์น˜ ๊ณ„์‚ฐ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ Python์˜ ๊ธ€๋กœ๋ฒŒ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋ฝ์€ ํ˜„๋Œ€์ ์ธ ๋ฉ€ํ‹ฐ์ฝ”์–ด CPU์˜ ํšจ์œจ์ ์ธ ์‚ฌ์šฉ์„ ์–ด๋ ต๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. Heinrich Kuttler, Manuel Kroiss ๋ฐ Paweล‚ Jurgielewicz๋Š” Python์—์„œ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ๊ตฌํ˜„์ด ์ž‘์—…์— ํšจ๊ณผ์ ์œผ๋กœ ํ™•์žฅ๋˜์ง€ ์•Š๊ณ  ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด ์ ํ•ฉํ•˜์ง€ ์•Š๋‹ค๊ณ  ๋ฐœ๊ฒฌํ–ˆ์Šต๋‹ˆ๋‹ค.

์ด ์Šค์ผ€์ผ๋ง ๋ณ‘๋ชฉํ˜„์ƒ์€ ํ•ต์‹ฌ์ ์ธ ์ˆซ์ž ๊ณ„์‚ฐ ์ž‘์—…์—๋งŒ ์žˆ๋Š” ๊ฒƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. Zachary DeVito์™€ Paweล‚ Jurgielewicz๋Š” Python์—์„œ์˜ ์กฐ์ •๊ณผ ํ†ต์‹ ์— ๋Œ€ํ•œ ์–ด๋ ค์›€์— ๋Œ€ํ•ด ์„ค๋ช…ํ–ˆ์Šต๋‹ˆ๋‹ค.## GIL(GLOBAL INTERPRETER LOCK) ์ œ๊ฑฐ

๊ฐœ์š”

GIL(GLOBAL INTERPRETER LOCK)์€ CPython์—์„œ ์‚ฌ์šฉ๋˜๋Š” ์Šค๋ ˆ๋“œ ๊ฐ„ ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜์œผ๋กœ, ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ Python ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ์–ดํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ GIL์€ ํ˜„์žฌ์˜ ๊ณผํ•™ ๋ฐ ์ˆซ์ž ๊ณ„์‚ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ์˜ ๊ฐœ๋ฐœ๊ณผ ์œ ์ง€๋ณด์ˆ˜์— ์–ด๋ ค์›€์„ ์ค„ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์„ค๊ณ„๋ฅผ ๋” ์–ด๋ ต๊ฒŒ ๋งŒ๋“ค๊ธฐ๋„ ํ•ฉ๋‹ˆ๋‹ค.

์ด PEP(ํŒŒ์ด์ฌ ๊ฐœ์„  ์ œ์•ˆ)์€ CPython์—์„œ GIL์„ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ œ์‹œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.

๋นŒ๋“œ ๊ตฌ์„ฑ ๋ณ€๊ฒฝ

GIL์€ CPython ๋นŒ๋“œ ๋ฐ python.org ๋‹ค์šด๋กœ๋“œ์˜ ๊ธฐ๋ณธ ์„ค์ •์œผ๋กœ ์œ ์ง€๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ƒˆ๋กœ์šด ๋นŒ๋“œ ๊ตฌ์„ฑ ํ”Œ๋ž˜๊ทธ์ธ --disable-gil์ด configure ์Šคํฌ๋ฆฝํŠธ์— ์ถ”๊ฐ€๋  ๊ฒƒ์ด๋ฉฐ, ์ด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ GIL ์—†์ด CPython์„ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋นŒ๋“œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

--disable-gil๋กœ ๋นŒ๋“œ๋œ CPython์€ Python/patchlevel.h์— ์žˆ๋Š” Py_NOGIL ๋งคํฌ๋กœ๋ฅผ ์ •์˜ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ABI ํƒœ๊ทธ์—๋Š” "n" (nogil์„ ์˜๋ฏธ)์ด ํฌํ•จ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

CPython์˜ --disable-gil ๋นŒ๋“œ๋Š” ์—ฌ์ „ํžˆ ๋Ÿฐํƒ€์ž„์—์„œ GIL์„ ์‚ฌ์šฉํ•˜์—ฌ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(PYTHONGIL ํ™˜๊ฒฝ ๋ณ€์ˆ˜ ๋ฐ Py_mod_gil ์Šฌ๋กฏ ์ฐธ์กฐ).

CPython ๋ณ€๊ฒฝ ์‚ฌํ•ญ ๊ฐœ์š”

GIL ์ œ๊ฑฐ์—๋Š” CPython ๋‚ด๋ถ€์— ์ƒ๋‹นํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํ•„์š”ํ•˜์ง€๋งŒ, ๊ณต๊ฐœ Python ๋ฐ C API์—๋Š” ์ƒ๋Œ€์ ์œผ๋กœ ์ ์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด ์„น์…˜์—์„œ๋Š” CPython ๊ตฌํ˜„์— ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์„ค๋ช…ํ•œ ๋‹ค์Œ, ์ œ์•ˆ๋œ API ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

๊ตฌํ˜„ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ๋‹ค์Œ ๋„ค ๊ฐ€์ง€ ๋ฒ”์ฃผ๋กœ ๊ทธ๋ฃนํ™”๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค:

  • ์ฐธ์กฐ ์นด์šดํŒ…
  • ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ
  • ์ปจํ…Œ์ด๋„ˆ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ
  • ์ž ๊ธˆ ๋ฐ ์›์ž์„ฑ API

์ฐธ์กฐ ์นด์šดํŒ…

GIL ์ œ๊ฑฐ๋Š” CPython์˜ ์ฐธ์กฐ ์นด์šดํŒ… ๊ตฌํ˜„์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์ฐธ์กฐ ์นด์šดํŒ…์ด ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜๊ณ , ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋‚ฎ์œผ๋ฉฐ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ํšจ์œจ์ ์œผ๋กœ ํ™•์žฅ๋  ์ˆ˜ ์žˆ๋„๋ก ๋งŒ๋“ค์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด PEP์€ ์ด๋Ÿฌํ•œ ์ œ์•ฝ ์‚ฌํ•ญ์— ๋Œ€์‘ํ•˜๊ธฐ ์œ„ํ•ด ์„ธ ๊ฐ€์ง€ ๊ธฐ์ˆ ์˜ ์กฐํ•ฉ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ๋Š” ์ผ๋ฐ˜ ๋น„์›์ž์  ์ฐธ์กฐ ์นด์šดํŒ…์—์„œ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ ์ฐธ์กฐ ์นด์šดํŒ…์œผ๋กœ์˜ ์ „ํ™˜์ž…๋‹ˆ๋‹ค. ์ด๋Š” ์›์ž์  ์ฐธ์กฐ ์นด์šดํŒ…๋ณด๋‹ค ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋‚ฎ์€ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ ์ฐธ์กฐ ์นด์šดํŒ… ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ ๋‘ ๊ฐ€์ง€ ๊ธฐ์ˆ ์€ ๋ถˆ๋ฉธํ™”(immortalization)์™€ ์ œํ•œ๋œ ํ˜•ํƒœ์˜ ์ง€์—ฐ ์ฐธ์กฐ ์นด์šดํŒ…์„ ํฌํ•จํ•˜๋ฉฐ, ์ฐธ์กฐ ์นด์šดํŒ…์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™•์žฅ์„ฑ ๋ฌธ์ œ ์ค‘ ์ผ๋ถ€๋ฅผ ํ•ด๊ฒฐํ•ฉ๋‹ˆ๋‹ค.

๋น„์›์ž์  ์ฐธ์กฐ ์นด์šดํŒ…์—์„œ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ ์ฐธ์กฐ ์นด์šดํŒ…์œผ๋กœ์˜ ์ „ํ™˜์€ Jiho Choi, Thomas Shull, Josep Torrellas์— ์˜ํ•ด 2018๋…„์— ์ฒ˜์Œ์œผ๋กœ ์†Œ๊ฐœ๋œ ๊ธฐ์ˆ ์ž…๋‹ˆ๋‹ค. ์ด ๊ธฐ์ˆ ์€ ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด๊ฐ€ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋„ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์— ์˜ํ•ด์„œ๋งŒ ์•ก์„ธ์Šค๋˜๋Š” ๊ฒƒ์„ ๊ด€์ฐฐํ•œ ๊ฒƒ์— ๊ธฐ๋ฐ˜ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ๊ฐ์ฒด๋Š” ์†Œ์œ  ์Šค๋ ˆ๋“œ(์ƒ์„ฑํ•œ ์Šค๋ ˆ๋“œ)์™€ ์—ฐ๊ฒฐ๋ฉ๋‹ˆ๋‹ค. ์†Œ์œ  ์Šค๋ ˆ๋“œ์—์„œ์˜ ์ฐธ์กฐ ์นด์šดํŒ… ์ž‘์—…์€ "๋กœ์ปฌ" ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด ์›์ž์ ์ด์ง€ ์•Š์€ ๋ช…๋ น์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” "๊ณต์œ " ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๊ธฐ ์œ„ํ•ด ์›์ž์  ๋ช…๋ น์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด ์„ค๊ณ„๋Š” ํ˜„์žฌ ํ”„๋กœ์„ธ์„œ์—์„œ ๋น„์šฉ์ด ๋งŽ์ด ๋“œ๋Š” ์›์ž์  ์ฝ๊ธฐ-์ˆ˜์ •-์“ฐ๊ธฐ ์—ฐ์‚ฐ์„ ํ”ผํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

์ด PEP์—์„œ ์ œ์•ˆํ•˜๋Š” BRC(์ฐธ์กฐ ์นด์šดํŒ…)์˜ ๊ตฌํ˜„์€ ๊ธฐ๋ณธ์ ์œผ๋กœ biased reference counting์˜ ์›๋ž˜ ์„ค๋ช…๊ณผ ๋งค์šฐ ์œ ์‚ฌํ•˜์ง€๋งŒ, ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ์˜ ํฌ๊ธฐ์™€ ํ•ด๋‹น ํ•„๋“œ์˜ ํŠน์ˆ˜ ๋น„ํŠธ ๋“ฑ ์„ธ๋ถ€ ์‚ฌํ•ญ์—์„œ ์ฐจ์ด๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. BRC๋Š” ๊ฐ ๊ฐ์ฒด์˜ ํ—ค๋”์— ์„ธ ๊ฐ€์ง€ ์ •๋ณด๋ฅผ ์ €์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค: "๋กœ์ปฌ" ์ฐธ์กฐ ์นด์šดํŠธ, "๊ณต์œ " ์ฐธ์กฐ ์นด์šดํŠธ, ์†Œ์œ  ์Šค๋ ˆ๋“œ์˜ ์‹๋ณ„์ž. BRC ๋…ผ๋ฌธ์€ ์ด๋Ÿฌํ•œ ์„ธ ๊ฐ€์ง€ ์š”์†Œ๋ฅผ ํ•˜๋‚˜์˜ 64๋น„ํŠธ ํ•„๋“œ๋กœ ์••์ถ•ํ•ฉ๋‹ˆ๋‹ค. ์ด PEP์€ ์ฐธ์กฐ ์นด์šดํŠธ ์˜ค๋ฒ„ํ”Œ๋กœ์šฐ๋กœ ์ธํ•œ ์ž ์žฌ์ ์ธ ๋ฌธ์ œ๋ฅผ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ๊ฐ์ฒด์˜ ํ—ค๋”์— ์„ธ ๊ฐœ์˜ ๋ณ„๋„ ํ•„๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ PEP์€ ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์— ์›์ž์  ์—ฐ์‚ฐ์„ ํ”ผํ•˜๋Š” ๋” ๋น ๋ฅธ ํ• ๋‹น ํ•ด์ œ ๊ฒฝ๋กœ๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

์ œ์•ˆ๋œ PyObject ๊ตฌ์กฐ์ฒด(๋˜๋Š” struct _object)๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

struct _object {
    _PyObject_HEAD_EXTRA
    uintptr_t ob_tid; // ์†Œ์œ  ์Šค๋ ˆ๋“œ id (4-8๋ฐ”์ดํŠธ)
    uint16_t __padding; // ๋ฏธ๋ž˜์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ์˜ˆ์•ฝ ๊ณต๊ฐ„ (2๋ฐ”์ดํŠธ)
    PyMutex ob_mutex; // ๊ฐœ๋ณ„ ๊ฐ์ฒด์˜ ๋ฎคํ…์Šค (1๋ฐ”์ดํŠธ)
    uint8_t ob_gc_bits; // ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ํ•„๋“œ (1๋ฐ”์ดํŠธ)
    uint32_t ob_ref_local; // ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ (4๋ฐ”์ดํŠธ)
    Py_ssize_t ob_ref_shared; // ๊ณต์œ  ์ฐธ์กฐ ์นด์šดํŠธ ๋ฐ ์ƒํƒœ ๋น„ํŠธ (4-8๋ฐ”์ดํŠธ)
    PyTypeObject ob_type;
};

๋ถˆ๋ฉธํ™”

์ผ๋ถ€ ๊ฐ์ฒด๋“ค์€ ํ”„๋กœ๊ทธ๋žจ์˜ ์ˆ˜๋ช… ๋™์•ˆ ๊ณ„์† ์œ ์ง€๋˜๋Š” interned ๋ฌธ์ž์—ด, ์ž‘์€ ์ •์ˆ˜, ์ •์ ์œผ๋กœ ํ• ๋‹น๋œ PyTypeObject ๋ฐ True, False, None ๊ฐ์ฒด์™€ ๊ฐ™์€ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ์ฒด๋“ค์€ ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ(ob_ref_local)๋ฅผ UINT32_MAX๋กœ ์„ค์ •ํ•˜์—ฌ ๋ถˆ๋ฉธ๋กœ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

๋ถˆ๋ฉธ ๊ฐ์ฒด์— ๋Œ€ํ•ด Py_INCREF ๋ฐ Py_DECREF ๋งคํฌ๋กœ๋Š” ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋กœ์จ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ด๋Ÿฌํ•œ ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ์— ์ ‘๊ทผํ•  ๋•Œ ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝํ•ฉ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.# Py_INCREF and Py_DECREF ๋งคํฌ๋กœ

Py_INCREF์™€ Py_DECREF ๋งคํฌ๋กœ๋Š” ๋ถˆ๋ณ€ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋ ‡๊ฒŒ ํ•จ์œผ๋กœ์จ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์ด๋Ÿฌํ•œ ๊ฐ์ฒด์— ์•ก์„ธ์Šคํ•  ๋•Œ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ์— ๋Œ€ํ•œ ๊ฒฝํ•ฉ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ์ œ์•ˆ๋œ ๋ถˆ๋ณ€ํ™” ์ฒด๊ณ„๋Š” Python 3.12์—์„œ ์ฑ„ํƒ๋œ PEP 683์™€ ๋งค์šฐ ์œ ์‚ฌํ•˜์ง€๋งŒ, ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ์˜ ๋ถˆ๋ณ€ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์•ฝ๊ฐ„ ๋‹ค๋ฅธ ๋น„ํŠธ ํ‘œํ˜„์„ ์‚ฌ์šฉํ•˜์—ฌ ํŽธํ–ฅ ์ฐธ์กฐ ์นด์šดํŒ…๊ณผ ์ง€์—ฐ ์ฐธ์กฐ ์นด์šดํŒ…๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๋„๋ก ์„ค๊ณ„๋˜์—ˆ์Šต๋‹ˆ๋‹ค. PEP 683 ๋ถˆ๋ณ€ํ™”๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ ๋„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค.

ํŽธํ–ฅ ์ฐธ์กฐ ์นด์šดํŒ…

ํŽธํ–ฅ ์ฐธ์กฐ ์นด์šดํŒ…์€ ํ˜„์žฌ ์Šค๋ ˆ๋“œ๊ฐ€ "์†Œ์œ "ํ•˜๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋น ๋ฅธ ๊ฒฝ๋กœ์™€ ๋‹ค๋ฅธ ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋Š๋ฆฐ ๊ฒฝ๋กœ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์†Œ์œ ๊ถŒ์€ ob_tid ํ•„๋“œ์— ์˜ํ•ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ ID๋ฅผ ๊ฒฐ์ •ํ•˜๊ธฐ ์œ„ํ•ด์„œ๋Š” ํ”Œ๋žซํผ๋ณ„ ์ฝ”๋“œ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ob_tid์— 0 ๊ฐ’์ด ์žˆ๋Š” ๊ฒฝ์šฐ, ํ•ด๋‹น ๊ฐ์ฒด๋Š” ์–ด๋–ค ์Šค๋ ˆ๋“œ๋„ ์†Œ์œ ํ•˜์ง€ ์•Š์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค.

ob_ref_local ํ•„๋“œ๋Š” ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ์™€ ๋‘ ๊ฐœ์˜ ํ”Œ๋ž˜๊ทธ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ์ƒ์œ„ 2๋น„ํŠธ๋Š” ๊ฐ์ฒด๊ฐ€ ๋ถˆ๋ณ€ ๊ฐ์ฒด์ธ์ง€ ๋˜๋Š” ์ง€์—ฐ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•˜๋Š”์ง€๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค (์ง€์—ฐ ์ฐธ์กฐ ์นด์šดํŒ…์— ๋Œ€ํ•ด์„œ๋Š” Deferred reference counting์„ ์ฐธ์กฐํ•˜์‹ญ์‹œ์˜ค).

ob_ref_shared ํ•„๋“œ๋Š” ๊ณต์œ  ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ๊ฐ€์žฅ ํ•˜์œ„ 2๋น„ํŠธ๋Š” ์ฐธ์กฐ ์นด์šดํŒ… ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ๊ณต์œ  ์ฐธ์กฐ ์นด์šดํŠธ๋Š” ์™ผ์ชฝ์œผ๋กœ 2๋น„ํŠธ ์‹œํ”„ํŠธ๋ฉ๋‹ˆ๋‹ค. ob_ref_shared ํ•„๋“œ๋Š” ๊ณต์œ  ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ ์ผ์‹œ์ ์œผ๋กœ ์Œ์ˆ˜๊ฐ€ ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฐ€์žฅ ํ•˜์œ„ ๋น„ํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด incref์™€ decref๊ฐ€ ์Šค๋ ˆ๋“œ ๊ฐ„์— ๊ท ํ˜•์„ ์ด๋ฃจ์ง€ ๋ชปํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฐ€๋Šฅํ•œ ์ฐธ์กฐ ์นด์šดํŒ… ์ƒํƒœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

0b00 - ๊ธฐ๋ณธ ์ƒํƒœ

0b01 - ์•ฝํ•œ ์ฐธ์กฐ

0b10 - ๋Œ€๊ธฐ ์ค‘์ธ ์ƒํƒœ

0b11 - ๋ณ‘ํ•ฉ๋œ ์ƒํƒœ

๊ฐ ์ƒํƒœ๋Š” ์ˆซ์ž์ ์œผ๋กœ ๋†’์€ ์ƒํƒœ๋กœ ์ „ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ฐ์ฒด๋Š” "๊ธฐ๋ณธ" ๋ฐ "๋ณ‘ํ•ฉ" ์ƒํƒœ์—์„œ๋งŒ ํ• ๋‹น ํ•ด์ œ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ƒํƒœ๋Š” ํ• ๋‹น ํ•ด์ œ ๋˜๊ธฐ ์ „์— "๋ณ‘ํ•ฉ" ์ƒํƒœ๋กœ ์ „ํ™˜ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ƒํƒœ ์ „ํ™˜์€ ob_ref_shared ํ•„๋“œ์— ๋Œ€ํ•œ ์›์ž์  ๋น„๊ต ๋ฐ ๊ต์ฒด๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ˆ˜ํ–‰๋ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ (0b00)

๊ฐ์ฒด๋Š” ๊ธฐ๋ณธ ์ƒํƒœ์—์„œ ์ดˆ๊ธฐ์— ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ด๊ฒƒ์€ ๋น ๋ฅธ ํ• ๋‹น ํ•ด์ œ ์ฝ”๋“œ ๊ฒฝ๋กœ๋งŒ ํ—ˆ์šฉํ•˜๋Š” ์œ ์ผํ•œ ์ƒํƒœ์ž…๋‹ˆ๋‹ค. ๊ทธ๋ ‡์ง€ ์•Š์œผ๋ฉด, ์Šค๋ ˆ๋“œ๋Š” ๋กœ์ปฌ ๋ฐ ๊ณต์œ  ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ๋ฅผ ๋ณ‘ํ•ฉํ•ด์•ผํ•˜๋ฉฐ, ์ด๋Š” ์›์ž์  ๋น„๊ต ๋ฐ ๊ต์ฒด๋ฅผ ํ•„์š”๋กœํ•ฉ๋‹ˆ๋‹ค.

์ด ๋น ๋ฅธ ํ• ๋‹น ํ•ด์ œ ์ฝ”๋“œ ๊ฒฝ๋กœ๋Š” ์•ฝํ•œ ์ฐธ์กฐ์˜ ๋™์‹œ์ ์ธ ์ฐธ์กฐ ํ•ด์ œ์™€ ์Šค๋ ˆ๋“œ ๊ฐ„์˜ ์ž ๊ธˆ ์—†๋Š” ๋ฆฌ์ŠคํŠธ ๋ฐ ์‚ฌ์ „ ์•ก์„ธ์Šค์™€ ํ•จ๊ป˜ ์‚ฌ์šฉ๋  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ, ์•ฝํ•œ ์ฐธ์กฐ๊ฐ€ ์ฒ˜์Œ์œผ๋กœ ์ƒ์„ฑ๋  ๋•Œ ๊ฐ์ฒด๊ฐ€ "๊ธฐ๋ณธ" ์ƒํƒœ์ธ ๊ฒฝ์šฐ "์•ฝํ•œ ์ฐธ์กฐ" ์ƒํƒœ๋กœ ์ „ํ™˜๋ฉ๋‹ˆ๋‹ค.

๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ๋น ๋ฅธ ํ• ๋‹น ํ•ด์ œ ์ฝ”๋“œ ๊ฒฝ๋กœ๋Š” ์ž ๊ธˆ ์—†๋Š” ๋ฆฌ์ŠคํŠธ ๋ฐ ์‚ฌ์ „ ์•ก์„ธ์Šค (Optimistically Avoiding Locking ์ฐธ์กฐ)๋กœ ์ธํ•ด ์†Œ์œ ํ•˜์ง€ ์•Š๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ฒ˜์Œ์œผ๋กœ "๊ธฐ๋ณธ" ์ƒํƒœ์˜ ๊ฐ์ฒด๋ฅผ ๊ฒ€์ƒ‰ํ•˜๋ ค๊ณ  ํ•  ๋•Œ ๋Š๋ฆฐ ์ž ๊ธˆ ์ฝ”๋“œ ๊ฒฝ๋กœ๋กœ ์ „ํ™˜๋˜๋ฉฐ, ๊ฐ์ฒด๊ฐ€ "์•ฝํ•œ ์ฐธ์กฐ" ์ƒํƒœ๋กœ ์ „ํ™˜๋ฉ๋‹ˆ๋‹ค.

์•ฝํ•œ ์ฐธ์กฐ (0b01)

์•ฝํ•œ ์ฐธ์กฐ ๋ฐ ๊ทธ ์ด์ƒ์˜ ์ƒํƒœ์— ์žˆ๋Š” ๊ฐ์ฒด๋Š” ์•ฝํ•œ ์ฐธ์กฐ ํ•ด์ œ ๋ฐ ์†Œ์œ ํ•˜์ง€ ์•Š๋Š” ์Šค๋ ˆ๋“œ์— ์˜ํ•œ ์ž ๊ธˆ ์—†๋Š” ๋ฆฌ์ŠคํŠธ ๋ฐ ์‚ฌ์ „ ์•ก์„ธ์Šค๋ฅผ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ํ• ๋‹น ํ•ด์ œ๋ฅผ ์œ„ํ•ด์„œ๋Š” ๋ณ‘ํ•ฉ ์ƒํƒœ๋กœ ์ „ํ™˜ํ•ด์•ผํ•˜๋ฉฐ, ์ด๋Š” "๊ธฐ๋ณธ" ์ƒํƒœ์—์„œ ์ง€์›๋˜๋Š” ๋น ๋ฅธ ํ• ๋‹น ํ•ด์ œ ์ฝ”๋“œ ๊ฒฝ๋กœ๋ณด๋‹ค ๋น„์šฉ์ด ๋” ๋งŽ์ด ๋“ญ๋‹ˆ๋‹ค.

๋Œ€๊ธฐ ์ค‘ (0b10)

๋Œ€๊ธฐ ์ค‘์ธ ์ƒํƒœ๋Š” ์†Œ์œ ํ•˜์ง€ ์•Š๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ๋ฅผ ๋ณ‘ํ•ฉํ•˜๋„๋ก ์š”์ฒญํ•œ ๊ฒƒ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๊ณต์œ  ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ ์Œ์ˆ˜๊ฐ€ ๋˜๋ฉด (์Šค๋ ˆ๋“œ ๊ฐ„์˜ incref ๋ฐ decref ๊ฐ„์˜ ๊ท ํ˜•์ด ๊นจ์ง„ ๊ฒฝ์šฐ), ๊ฐ์ฒด๋Š” ์†Œ์œ ํ•˜๋Š” ์Šค๋ ˆ๋“œ์˜ ๋ณ‘ํ•ฉ ๋Œ€๊ธฐ์—ด์— ์‚ฝ์ž…๋ฉ๋‹ˆ๋‹ค. ์†Œ์œ ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” eval_breaker ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ํ†ตํ•ด ์•Œ๋ฆผ์„ ๋ฐ›์Šต๋‹ˆ๋‹ค. ์‹ค์ œ๋กœ์ด ์ž‘์—…์€ ๋“œ๋ฌผ๊ฒŒ ๋ฐœ์ƒํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด๋Š” ๋‹จ์ผ ์Šค๋ ˆ๋“œ์— ์˜ํ•ด๋งŒ ์•ก์„ธ์Šค๋˜๋ฉฐ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์— ์˜ํ•ด ์•ก์„ธ์Šค๋˜๋Š” ๊ฒฝ์šฐ์—๋„ ์Œ์ˆ˜์ธ ๊ณต์œ  ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ๊ฐ€์ง€๋Š” ๊ฐ์ฒด๋Š” ๋“œ๋ฌผ๊ฒŒ ์žˆ์Šต๋‹ˆ๋‹ค.

์†Œ์œ ํ•˜๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋œ ๊ฒฝ์šฐ, ์ž‘๋™ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” ์ฆ‰์‹œ ๋กœ์ปฌ ๋ฐ ๊ณต์œ  ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ๋ฅผ ๋ณ‘ํ•ฉํ•˜๊ณ  ๋ณ‘ํ•ฉ๋œ ์ƒํƒœ๋กœ ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

๋ณ‘ํ•ฉ (0b11)

๋ณ‘ํ•ฉ๋œ ์ƒํƒœ๋Š” ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค ์Šค๋ ˆ๋“œ๋„ ์†Œ์œ ํ•˜์ง€ ์•Š์Œ์„ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. ๋ณ‘ํ•ฉ๋œ ์ƒํƒœ์—์„œ ob_tid ํ•„๋“œ๋Š” 0์ด๊ณ  ob_ref_local์€ ์‚ฌ์šฉ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ณต์œ  ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0์ด ๋˜๋ฉด ๊ฐ์ฒด๋Š” ๋ณ‘ํ•ฉ๋œ ์ƒํƒœ์—์„œ ํ• ๋‹น ํ•ด์ œ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ฐธ์กฐ ์นด์šดํŒ… ์˜์‚ฌ ์ฝ”๋“œ

๋‹ค์Œ์€ ์ œ์•ˆ๋œ Py_INCREF ๋ฐ Py_DECREF ์ž‘์—…์˜ ๋™์ž‘์„ ์„ค๋ช…ํ•˜๋Š” ์˜์‚ฌ ์ฝ”๋“œ(C ์Šคํƒ€์ผ)์ž…๋‹ˆ๋‹ค:

// "ob_ref_shared"์˜ ํ•˜์œ„ 2๋น„ํŠธ๋Š” ํ”Œ๋ž˜๊ทธ๋กœ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

define _Py_SHARED_SHIFT 2

void Py_INCREF(PyObject *op) {
    uint32_t new_local = op->ob_ref_local + 1;
    if (new_local == _Py_IMMORTAL_REFCNT)
        return;  // object is immortal
    if (op->ob_tid == _Py_ThreadId())
        op->ob_ref_local = new_local;
    else
        atomic_add(&op->ob_ref_shared, 1 << _Py_SHARED_SHIFT);
}

void Py_DECREF(PyObject *op) {
    if (op->ob_ref_local == _Py_IMMORTAL_REFCNT)
        return;  // object is immortal
    if (op->ob_tid == _Py_ThreadId())
        op->ob_ref_local--;
    else if (op->ob_ref_local == _Py_MergeZeroRefcount())
        // merge refcount
    else
        _Py_DecRefShared();  // slow path
}

void _Py_MergeZeroRefcount(PyObject *op) {
    if (op->ob_ref_shared == 0)
        // quick deallocation code path (common case)
        op->ob_tid = 0;
}# merge refcount


else
    _Py_DecRefShared();

slow path

void _Py_MergeZeroRefcount(PyObject *op)
{
    if (op->ob_ref_shared == 0)
    {
        // quick deallocation code path (common case)
        _Py_Dealloc(op);
    }
    else
    {
        // slower merging path not shown
    }
}

์ฐธ์กฐ ๊ตฌํ˜„์ฒด์—๋Š” _Py_MergeZeroRefcount์™€ _Py_DecRefShared์˜ ๊ตฌํ˜„์ด ํฌํ•จ๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค.

์œ„์˜ ์ฝ”๋“œ๋Š” ์˜์‚ฌ ์ฝ”๋“œ์ด๋ฉฐ, ์‹ค์ œ๋กœ๋Š” C ๋ฐ C++์—์„œ ์ •์˜๋˜์ง€ ์•Š์€ ๋™์ž‘์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด "relaxed atomics"๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ob_tid์™€ ob_ref_local์— ์•ก์„ธ์Šคํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…

์ผ๋ถ€ ์œ ํ˜•์˜ ๊ฐ์ฒด(์˜ˆ: ์ตœ์ƒ์œ„ ํ•จ์ˆ˜, ์ฝ”๋“œ ๊ฐ์ฒด, ๋ชจ๋“ˆ ๋ฐ ๋ฉ”์„œ๋“œ)๋Š” ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ๋™์‹œ์— ์ž์ฃผ ์•ก์„ธ์Šค๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ์ฒด๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์ˆ˜๋ช… ๋™์•ˆ ์กด์žฌํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ถˆ๋ฉธํ™”๋Š” ์ ํ•ฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด PEP๋Š” ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ด๋Ÿฌํ•œ ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ์— ๋Œ€ํ•œ ๊ฒฝํ•ฉ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์ œํ•œ๋œ ํ˜•ํƒœ์˜ ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.

์ผ๋ฐ˜์ ์œผ๋กœ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” ๊ฐ์ฒด๋ฅผ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์Šคํƒ์— ํ‘ธ์‹œํ•˜๊ณ  ํŒํ•  ๋•Œ ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์ˆ˜์ •ํ•ฉ๋‹ˆ๋‹ค. ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•ด ์ด๋Ÿฌํ•œ ์ฐธ์กฐ ์นด์šดํŒ… ์ž‘์—…์„ ๊ฑด๋„ˆ๋œ๋‹ˆ๋‹ค. ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์ง€์›ํ•˜๋Š” ๊ฐ์ฒด๋Š” ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ์˜ ๊ฐ€์žฅ ์ƒ์œ„ 2๋น„ํŠธ๋ฅผ 1๋กœ ์„ค์ •ํ•˜์—ฌ ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค.

์ฐธ์กฐ ์นด์šดํŒ… ์ž‘์—…์ด ๊ฑด๋„ˆ๋›ฐ์–ด์ง€๊ธฐ ๋•Œ๋ฌธ์— ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ๋Š” ์ด์ œ ์ด๋Ÿฌํ•œ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์‹ค์ œ ์ฐธ์กฐ ์ˆ˜๋ฅผ ๋ฐ˜์˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ์ฐธ์กฐ ์นด์šดํŠธ๋Š” ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ์˜ ํ•ฉ๊ณผ ๊ฐ ์Šค๋ ˆ๋“œ์˜ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์Šคํƒ์—์„œ ๊ฑด๋„ˆ๋›ด ์ฐธ์กฐ์˜ ํ•ฉ์ž…๋‹ˆ๋‹ค. ์‹ค์ œ ์ฐธ์กฐ ์นด์šดํŠธ๋Š” ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘ ์ค‘ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ์ผ์‹œ ์ค‘์ง€๋  ๋•Œ๋งŒ ์•ˆ์ „ํ•˜๊ฒŒ ๊ณ„์‚ฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ์ฒด๋Š” ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘ ์ฃผ๊ธฐ ๋™์•ˆ์—๋งŒ ํ•ด์ œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ์ฒด๋Š” ์ด๋ฏธ CPython์—์„œ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์ฐธ์กฐ ์‚ฌ์ดํด์„ ํ˜•์„ฑํ•˜๋ฏ€๋กœ ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ… ์—†์ด๋„ ์ผ๋ฐ˜์ ์œผ๋กœ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ์— ์˜ํ•ด ํ•ด์ œ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ตœ์ƒ์œ„ ํ•จ์ˆ˜์™€ ๋ชจ๋“ˆ์€ ์ฐธ์กฐ ์‚ฌ์ดํด์„ ํ˜•์„ฑํ•˜๋ฉฐ, ๋ฉ”์„œ๋“œ์™€ ํƒ€์ž… ๊ฐ์ฒด๋„ ์ฐธ์กฐ ์‚ฌ์ดํด์„ ํ˜•์„ฑํ•ฉ๋‹ˆ๋‹ค.

์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์œ„ํ•œ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ ์ˆ˜์ •

์ถ”์  ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ๋Š” ์ฐธ์กฐ๋˜์ง€ ์•Š์€ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. ํ˜„์žฌ ์ถ”์  ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ๋Š” ์ฐธ์กฐ ์‚ฌ์ดํด์˜ ์ผ๋ถ€์ธ ์ฐธ์กฐ๋˜์ง€ ์•Š์€ ๊ฐ์ฒด๋งŒ ์ฐพ์Šต๋‹ˆ๋‹ค. ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•˜๋ฉด ์ถ”์  ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ๋Š” ์ฐธ์กฐ ์‚ฌ์ดํด์— ์†ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋Š” ์ผ๋ถ€ ์ฐธ์กฐ๋˜์ง€ ์•Š์€ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋Š” ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์œผ๋กœ ์ธํ•ด ์ˆ˜์ง‘์ด ์ง€์—ฐ๋œ ๊ฐ์ฒด์ž…๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์ง€์›ํ•˜๋Š” ๋ชจ๋“  ๊ฐ์ฒด๋Š” ์ถ”์  ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘์„ ์ง€์›ํ•˜๋Š” ํ•ด๋‹น ์œ ํ˜• ๊ฐ์ฒด(through the Py_TPFLAGS_HAVE_GC ํ”Œ๋ž˜๊ทธ๋ฅผ ํ†ตํ•ด)๋„ ๊ฐ€์ ธ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ๋Š” ๊ฐ ์Šค๋ ˆ๋“œ์˜ ์Šคํƒ์„ ํŠธ๋ž˜๋ฒ„์Šคํ•˜์—ฌ ๊ฐ ์ปฌ๋ ‰์…˜์˜ ์‹œ์ž‘ ์‹œ GC ์ฐธ์กฐ ์นด์šดํŠธ์— ์ฐธ์กฐ๋ฅผ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ฐธ์กฐ ์นด์šดํŒ… ์œ ํ˜• ๊ฐ์ฒด

์œ ํ˜• ๊ฐ์ฒด(PyTypeObject)๋Š” ์ฐธ์กฐ ์นด์šดํŒ… ๊ธฐ์ˆ ์„ ํ˜ผํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ •์ ์œผ๋กœ ํ• ๋‹น๋œ ์œ ํ˜• ๊ฐ์ฒด๋Š” ์ด๋ฏธ ํ”„๋กœ๊ทธ๋žจ์˜ ์ˆ˜๋ช… ๋™์•ˆ ์กด์žฌํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ถˆ๋ฉธํ™”๋ฉ๋‹ˆ๋‹ค. ํž™ ์œ ํ˜• ๊ฐ์ฒด๋Š” ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…๊ณผ ์Šค๋ ˆ๋“œ๋ณ„ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์กฐํ•ฉํ•˜์—ฌ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํž™ ์œ ํ˜•์˜ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™•์žฅ ๋ณ‘๋ชฉํ˜„์ƒ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ํž™ ์œ ํ˜•์— ๋Œ€ํ•œ ๋Œ€๋ถ€๋ถ„์˜ ์ฐธ์กฐ๋Š” ์ธ์Šคํ„ด์Šค์˜ ์ฐธ์กฐ๊ฐ€ ์•„๋‹Œ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์Šคํƒ์— ์žˆ๋Š” ์ฐธ์กฐ์ž…๋‹ˆ๋‹ค.

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ํž™ ์œ ํ˜•์˜ ์ฐธ์กฐ ์นด์šดํŠธ๋Š” ์Šค๋ ˆ๋“œ๋ณ„ ๋ฐฐ์—ด์— ๋ถ„์‚ฐํ•˜์—ฌ ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๊ฐ ์Šค๋ ˆ๋“œ๋Š” ๊ฐ ํž™ ์œ ํ˜• ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ ๋ฐฐ์—ด์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ํž™ ์œ ํ˜• ๊ฐ์ฒด์—๋Š” ๊ณ ์œ ํ•œ ๋ฒˆํ˜ธ๊ฐ€ ํ• ๋‹น๋˜์–ด ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ ๋ฐฐ์—ด์—์„œ์˜ ์œ„์น˜๋ฅผ ๊ฒฐ์ •ํ•ฉ๋‹ˆ๋‹ค. ํž™ ์œ ํ˜•์˜ ์‹ค์ œ ์ฐธ์กฐ ์นด์šดํŠธ๋Š” ์Šค๋ ˆ๋“œ๋ณ„ ๋ฐฐ์—ด์˜ ํ•ญ๋ชฉ๋“ค์˜ ํ•ฉ, PyTypeObject์˜ ์ฐธ์กฐ ์นด์šดํŠธ ๋ฐ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์Šคํƒ์—์„œ์˜ ์ง€์—ฐ๋œ ์ฐธ์กฐ๋ฅผ ๋”ํ•œ ๊ฐ’์ž…๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ๋Š” ์œ ํ˜• ๊ฐ์ฒด์˜ ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์ฆ๊ฐ€ ๋˜๋Š” ๊ฐ์†Œํ•  ๋•Œ ํ•„์š”์— ๋”ฐ๋ผ ์ž์ฒด ์œ ํ˜• ์ฐธ์กฐ ์นด์šดํŠธ ๋ฐฐ์—ด์„ ํ™•์žฅํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ๋ณ„ ์ฐธ์กฐ ์นด์šดํŠธ ๋ฐฐ์—ด์˜ ์‚ฌ์šฉ์€ ๋ช‡ ๊ตฐ๋ฐ๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค:

  • PyType_GenericAlloc(PyTypeObject *type, Py_ssize_t nitems): ํž™ ์œ ํ˜•์ธ ๊ฒฝ์šฐ ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ ์œ ํ˜•์— ๋Œ€ํ•œ ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ต๋‹ˆ๋‹ค.
  • subtype_dealloc(PyObject *self): ํž™ ์œ ํ˜•์ธ ๊ฒฝ์šฐ ํ˜„์žฌ ์Šค๋ ˆ๋“œ์˜ self->ob_type์— ๋Œ€ํ•œ ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ๊ฐ์†Œ์‹œํ‚ต๋‹ˆ๋‹ค.
  • gcmodule.c: ๊ฐ ์Šค๋ ˆ๋“œ์˜ ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ํ•ด๋‹น ํž™ ์œ ํ˜• ๊ฐ์ฒด์˜ gc_refs ์นด์šดํŠธ์— ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ ์Šค๋ ˆ๋“œ๊ฐ€ ์ข…๋ฃŒ๋  ๋•Œ๋Š” ๋ชจ๋“  ์œ ํ˜• ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ์— ๋Œ€ํ•ด 0์ด ์•„๋‹Œ ๋กœ์ปฌ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ# ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

CPython์€ ํ˜„์žฌ ์ž‘์€ ๊ฐ์ฒด ํ• ๋‹น์— ์ตœ์ ํ™”๋œ ๋‚ด๋ถ€ ํ• ๋‹น์ž์ธ pymalloc์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ pymalloc์€ GIL ์—†์ด๋Š” ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด PEP๋Š” pymalloc์„ mimalloc์œผ๋กœ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. mimalloc์€ ์ž‘์€ ํ• ๋‹น์—๋„ ์ข‹์€ ์„ฑ๋Šฅ์„ ๊ฐ€์ง€๋ฉฐ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ ๋ฒ”์šฉ ํ• ๋‹น์ž์ž…๋‹ˆ๋‹ค.

mimalloc์„ ์‚ฌ์šฉํ•˜๋ฉด GIL์„ ์ œ๊ฑฐํ•˜๋Š” ๋ฐ ๊ด€๋ จ๋œ ๋‘ ๊ฐ€์ง€ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฒซ์งธ, ๋‚ด๋ถ€ mimalloc ๊ตฌ์กฐ๋ฅผ ํƒ์ƒ‰ํ•จ์œผ๋กœ์จ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๊ฐ€ ์—ฐ๊ฒฐ๋œ ๋ชฉ๋ก์„ ์œ ์ง€ํ•˜์ง€ ์•Š๊ณ ๋„ ๋ชจ๋“  Python ๊ฐ์ฒด๋ฅผ ์ฐพ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์„น์…˜์—์„œ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ๋‘˜์งธ, mimalloc ํž™๊ณผ ์‚ฌ์ด์ฆˆ ํด๋ž˜์Šค์— ๊ธฐ๋ฐ˜ํ•œ ํ• ๋‹น์€ dict์™€ ๊ฐ™์€ ์ปฌ๋ ‰์…˜์—์„œ ์ฝ๊ธฐ ์ „์šฉ ์ž‘์—… ์ค‘์— ์ผ๋ฐ˜์ ์œผ๋กœ ์ž ๊ธˆ์„ ํš๋“ํ•˜์ง€ ์•Š๋„๋ก ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์— ๋Œ€ํ•œ ์ž์„ธํ•œ ๋‚ด์šฉ์€ ์ปฌ๋ ‰์…˜ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ ์„น์…˜์—์„œ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

CPython์€ ์ด๋ฏธ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์„ ์ง€์›ํ•˜๋Š” ๊ฐ์ฒด๊ฐ€ GC ํ• ๋‹น์ž API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค๋Š” ์š”๊ตฌ ์‚ฌํ•ญ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค (์ผ๋ฐ˜์ ์œผ๋กœ PyType_GenericAlloc๋ฅผ ํ˜ธ์ถœํ•จ์œผ๋กœ์จ ๊ฐ„์ ‘์ ์œผ๋กœ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค). ์ด PEP๋Š” Python ํ• ๋‹น์ž API์˜ ์‚ฌ์šฉ์— ๋Œ€ํ•œ ์ถ”๊ฐ€์ ์ธ ์š”๊ตฌ ์‚ฌํ•ญ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ๋จผ์ €, Python ๊ฐ์ฒด๋Š” PyType_GenericAlloc, PyObject_Malloc ๋˜๋Š” ํ•ด๋‹น ํ˜ธ์ถœ์„ ๋ž˜ํ•‘ํ•˜๋Š” ๋‹ค๋ฅธ Python API์™€ ๊ฐ™์€ ๊ฐ์ฒด ํ• ๋‹น API๋ฅผ ํ†ตํ•ด ํ• ๋‹น๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Python ๊ฐ์ฒด๋Š” C์˜ malloc ๋˜๋Š” C++์˜ new ์—ฐ์‚ฐ์ž์™€ ๊ฐ™์€ ๋‹ค๋ฅธ API๋ฅผ ํ†ตํ•ด ํ• ๋‹นํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, PyObject_Malloc์€ Python ๊ฐ์ฒด๋งŒ ํ• ๋‹นํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜์–ด์•ผ ํ•˜๋ฉฐ ๋ฒ„ํผ, ์ €์žฅ์†Œ ๋˜๋Š” PyObjects๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ํ• ๋‹นํ•˜๋Š” ๋ฐ ์‚ฌ์šฉํ•ด์„œ๋Š” ์•ˆ ๋ฉ๋‹ˆ๋‹ค.

์ด PEP์€ ํ”Œ๋Ÿฌ๊ทธ ๊ฐ€๋Šฅํ•œ ํ• ๋‹น์ž API(PyMem_SetAllocator)์—๋„ ์ œํ•œ์„ ๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. GIL ์—†์ด ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒฝ์šฐ ์ด API๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์„ค์ •๋œ ํ• ๋‹น์ž๋Š” Python ๊ฐ์ฒด ํ• ๋‹น์„ ์œ„ํ•ด PyObject_Malloc๊ณผ ๊ฐ™์€ ํ•ด๋‹นํ•˜๋Š” ํ•˜์œ„ ํ• ๋‹น์ž๋กœ ํ• ๋‹น์„ ์œ„์ž„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด Python์˜ tracemalloc๊ณผ ๋””๋ฒ„๊ทธ ํ• ๋‹น์ž์™€ ๊ฐ™์ด ํ•˜์œ„ ํ• ๋‹น์ž๋ฅผ "๋ž˜ํ•‘"ํ•˜๋Š” ํ• ๋‹น์ž๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ํ• ๋‹น์ž๋ฅผ ์™„์ „ํžˆ ๋Œ€์ฒดํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

CPython ์ž์œ  ๋ฆฌ์ŠคํŠธ

CPython์€ ํŠœํ”Œ์ด๋‚˜ ์ˆซ์ž์™€ ๊ฐ™์ด ์ž์ฃผ ํ• ๋‹น๋˜๋Š” ์ž‘์€ ๊ฐ์ฒด์˜ ํ• ๋‹น ์†๋„๋ฅผ ๋†’์ด๊ธฐ ์œ„ํ•ด ์ž์œ  ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž์œ  ๋ฆฌ์ŠคํŠธ๋Š” ๊ฐœ๋ณ„ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ƒํƒœ์—์„œ PyThreadState๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ (Cycle Collection)

CPython ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ์ด ์ œ์•ˆ๊ณผ ํ•จ๊ป˜ ์ž‘๋™ํ•˜๊ธฐ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

GIL์ด ์ด์ „์— ์ œ๊ณตํ–ˆ๋˜ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ ๋ณด์žฅ์„ ์œ„ํ•ด "stop-the-world" ์‚ฌ์šฉ

๋น„ ์„ธ๋Œ€์ ์ธ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ์„ธ๋Œ€์ ์ธ ์ปฌ๋ ‰ํ„ฐ ๋Œ€์‹  ์‚ฌ์šฉ

์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ… ๋ฐ ํŽธํ–ฅ๋œ ์ฐธ์กฐ ์นด์šดํŒ…๊ณผ์˜ ํ†ตํ•ฉ

๋˜ํ•œ ์œ„์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ GC ๊ฐ์ฒด์—์„œ _gc_prev ๋ฐ _gc_next ํ•„๋“œ๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ถ”์ ๋œ ์ƒํƒœ, ์™„๋ฃŒ๋œ ์ƒํƒœ ๋ฐ ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ์ƒํƒœ๋ฅผ ์ €์žฅํ•˜๋˜ GC ๋น„ํŠธ๋Š” PyObject ํ—ค๋”์˜ ob_gc_bits ํ•„๋“œ๋กœ ์ด๋™ํ•ฉ๋‹ˆ๋‹ค.

Stop-the-World

ํ˜„์žฌ CPython ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ์‚ฌ์ดํด์„ ์ฐพ๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ Python ๊ฐ์ฒด์— ์•ก์„ธ์Šคํ•˜์ง€ ๋ชปํ•˜๋„๋ก ์ „์—ญ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋ฝ(GIL)์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. GIL์€ ์‚ฌ์ดํด ๊ฒ€์ƒ‰ ๋ฃจํ‹ด ์ค‘์— ์ ˆ๋Œ€๋กœ ํ•ด์ œ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์ปฌ๋ ‰ํ„ฐ๋Š” ์•ˆ์ •์ ์ธ(์ฆ‰, ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š”) ์ฐธ์กฐ ์นด์šดํŠธ์™€ ์ฐธ์กฐ๋ฅผ ์‚ฌ์ดํด ๊ฒ€์ƒ‰ ๋ฃจํ‹ด์˜ ์ง€์† ์‹œ๊ฐ„ ๋™์•ˆ ์˜์กดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์‚ฌ์ดํด ๊ฐ์ง€ ์ดํ›„์—๋Š” GIL์ด ์ผ์‹œ์ ์œผ๋กœ ํ•ด์ œ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๊ฐ์ฒด์˜ ์ตœ์ข…ํ™”์ž์™€ clear(tp_clear) ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ต์ฐจ๋กœ ์‹คํ–‰๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

GIL ์—†์ด ์‹คํ–‰๋  ๋•Œ ๊ตฌํ˜„์€ ์‚ฌ์ดํด ๊ฒ€์ถœ ์ค‘์— ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ ์•ˆ์ •์ ์ธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ๋Š” ๋ฐฉ๋ฒ•์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Python ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” ์ฐธ์กฐ์™€ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ ์•ˆ์ •์ ์ธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ผ์‹œ์ ์œผ๋กœ ์ผ์‹œ ์ •์ง€๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์ดํด์ด ์‹๋ณ„๋˜๋ฉด ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋‹ค์‹œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.

ํ˜„์žฌ CPython ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ๊ฐ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์ฃผ๊ธฐ์—์„œ ๋‘ ๊ฐœ์˜ ์‚ฌ์ดํด ๊ฒ€์ถœ ํŒจ์Šค๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ GIL ์—†์ด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ๋Š” ๋‘ ๊ฐœ์˜ stop-the-world ์ผ์‹œ ์ •์ง€๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ฒซ ๋ฒˆ์งธ ์‚ฌ์ดํด ๊ฒ€์ถœ ํŒจ์Šค๋Š” ์ˆœํ™˜ ์“ฐ๋ ˆ๊ธฐ๋ฅผ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋ฒˆ์งธ ํŒจ์Šค๋Š” ์ตœ์ข…ํ™”์ž ์ดํ›„์— ์‹คํ–‰๋˜์–ด ์—ฌ์ „ํžˆ ๋„๋‹ฌํ•  ์ˆ˜ ์—†๋Š” ๊ฐ์ฒด๋ฅผ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์ตœ์ข…ํ™”์ž์™€ tp_clear ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๊ธฐ ์ „์— ๋‹ค์‹œ ์‹œ์ž‘๋˜๋ฏ€๋กœ ํ˜„์žฌ CPython ๋™์ž‘๊ณผ ๋‹ฌ๋ฆฌ ์ž ์žฌ์ ์ธ ๋ฐ๋“œ๋ฝ์„ ๋ฐœ์ƒ์‹œํ‚ค์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

์Šค๋ ˆ๋“œ ์ƒํƒœ

๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์„ ์œ„ํ•ด ์Šค๋ ˆ๋“œ๋ฅผ ์ผ์‹œ ์ •์ง€ํ•˜๊ธฐ ์œ„ํ•ด PyThreadState์— ์ƒˆ๋กœ์šด "status" ํ•„๋“œ๊ฐ€ ์ถ”๊ฐ€๋ฉ๋‹ˆ๋‹ค. PyThreadState์˜ ๋‹ค๋ฅธ ํ•„๋“œ์™€ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ status ํ•„๋“œ๋Š” ๊ณต๊ฐœ CPython API์˜ ์ผ๋ถ€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. status ํ•„๋“œ๋Š” ๋‹ค์Œ ์„ธ ๊ฐ€์ง€ ์ƒํƒœ ์ค‘ ํ•˜๋‚˜๋ฅผ ๊ฐ€์งˆ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ATTACHED
  • DETACHED
  • GC

ATTACHED์™€ DETACHED ์ƒํƒœ๋Š” ์ด์ „๊ณผ ๋™์ผํ•˜๊ฒŒ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. GC ์ƒํƒœ๋Š” ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์ค‘์ธ ์Šค๋ ˆ๋“œ์— ๋Œ€ํ•ด ์„ค์ •๋ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ƒํƒœ๋Š” ๋™์‹œ์— ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์„ ์‹œ์ž‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด PyEval_RestoreThread ํ•จ์ˆ˜๊ฐ€ ์ˆ˜์ •๋ฉ๋‹ˆ๋‹ค.### ATTACHED์™€ DETACHED

  • GC(Garbage Collection)๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ์Šค๋ ˆ๋“œ๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ Python ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•˜์ง€ ์•Š๋„๋ก ๋ณด์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋Š” "GC" ์ƒํƒœ์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • GC ์Šค๋ ˆ๋“œ๋Š” ์ƒํƒœ ํ•„๋“œ์— ๋Œ€ํ•ด ์›์ž์ ์ธ compare-and-swap ์—ฐ์‚ฐ์„ ์‚ฌ์šฉํ•˜์—ฌ DETACHED ์ƒํƒœ์—์„œ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋ฅผ GC ์ƒํƒœ๋กœ ์ „ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ATTACHED ์ƒํƒœ์— ์žˆ๋Š” ์Šค๋ ˆ๋“œ๋Š” ๊ธฐ์กด์˜ "eval breaker" ๋ฉ”์ปค๋‹ˆ์ฆ˜์„ ์‚ฌ์šฉํ•˜์—ฌ ์Šค์Šค๋กœ ์ผ์‹œ ์ •์ง€ํ•˜๊ณ  ์ƒํƒœ๋ฅผ "GC"๋กœ ์„ค์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • stop-the-world ์ผ์‹œ ์ •์ง€๊ฐ€ ๋๋‚˜๋ฉด, "GC" ์ƒํƒœ์ธ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋Š” DETACHED๋กœ ์„ค์ •๋˜๊ณ  ์ผ์‹œ ์ •์ง€๋œ ๊ฒฝ์šฐ ๊นจ์–ด๋‚ฉ๋‹ˆ๋‹ค.
  • ์ด์ „์— ATTACHED ์ƒํƒœ์˜€๋˜ (์ฆ‰, Python ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ ์ค‘์ด๋˜) ์Šค๋ ˆ๋“œ๋Š” ๋‹ค์‹œ ATTACHED๋กœ ์ฒจ๋ถ€ํ•˜๊ณ  Python ์ฝ”๋“œ๋ฅผ ๊ณ„์† ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด์ „์— DETACHED ์ƒํƒœ์˜€๋˜ ์Šค๋ ˆ๋“œ๋Š” ์•Œ๋ฆผ์„ ๋ฌด์‹œํ•ฉ๋‹ˆ๋‹ค.

Generations

  • ๊ธฐ์กด์˜ Python ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ์„ธ ๊ฐ€์ง€ ์„ธ๋Œ€(generation)๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
  • GIL ์—†์ด ์ปดํŒŒ์ผํ•˜๋Š” ๊ฒฝ์šฐ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ๋‹จ์ผ ์„ธ๋Œ€๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค(์ฆ‰, ์„ธ๋Œ€์ ์ด์ง€ ์•Š์Šต๋‹ˆ๋‹ค).
  • ์ด ๋ณ€๊ฒฝ์˜ ์ฃผ์š” ์ด์œ ๋Š” ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ stop-the-world ์ผ์‹œ ์ •์ง€์˜ ์˜ํ–ฅ์„ ์ค„์ด๊ธฐ ์œ„ํ•œ ๊ฒƒ์ž…๋‹ˆ๋‹ค.
  • ์–ด๋ฆฐ ์„ธ๋Œ€๋ฅผ ์ˆ˜์ง‘ํ•˜๊ธฐ ์œ„ํ•œ ๋นˆ๋ฒˆํ•œ stop-the-world ์ผ์‹œ ์ •์ง€๋Š” ์ ์€ ๋นˆ๋„์˜ ์ˆ˜์ง‘๋ณด๋‹ค ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ๋” ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

Deferred์™€ Biased ์ฐธ์กฐ ์นด์šดํŒ…๊ณผ์˜ ํ†ตํ•ฉ

  • ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ์ฐธ์กฐ๋˜์ง€ ์•Š์€ ๊ฐ์ฒด๋ฅผ ์ฐพ๊ธฐ ์œ„ํ•ด ์ฐธ์กฐ ์ˆ˜์™€ ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ์˜ ์ฐจ์ด๋ฅผ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค.
  • ์ด ์ฐจ์ด๋Š” gc_refs๋ผ๊ณ  ํ•˜๋ฉฐ _gc_prev ํ•„๋“œ์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค.
  • gc_refs๊ฐ€ ์–‘์ˆ˜์ด๋ฉด ๊ฐ์ฒด๊ฐ€ ์‚ด์•„์žˆ์Œ(์ฆ‰, ์ˆœํ™˜ ์“ฐ๋ ˆ๊ธฐ๊ฐ€ ์•„๋‹˜)์ด ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค.
  • gc_refs๊ฐ€ 0์ด๋ฉด ๊ฐ์ฒด๋Š” ๋‹ค๋ฅธ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด์— ์˜ํ•ด ์ด์ „์— ์ฐธ์กฐ๋˜์—ˆ๋Š”์ง€์— ๋”ฐ๋ผ ์‚ด์•„์žˆ์„ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ์ด ์ฐจ์ด๋ฅผ ๊ณ„์‚ฐํ•  ๋•Œ, ์ปฌ๋ ‰ํ„ฐ๋Š” ๊ฐ ์Šค๋ ˆ๋“œ์˜ ์Šคํƒ์„ ํƒ์ƒ‰ํ•˜๊ณ  ๊ฐ ์ง€์—ฐ ์ฐธ์กฐ์— ๋Œ€ํ•ด ์ฐธ์กฐ๋œ ๊ฐ์ฒด์˜ gc_refs๋ฅผ ์ฆ๊ฐ€์‹œ์ผœ์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ์ œ๋„ˆ๋ ˆ์ดํ„ฐ ๊ฐ์ฒด๋„ ์ง€์—ฐ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง„ ์Šคํƒ์„ ๊ฐ€์ง€๊ณ  ์žˆ์œผ๋ฏ€๋กœ ๋™์ผํ•œ ์ ˆ์ฐจ๊ฐ€ ๊ฐ ์ œ๋„ˆ๋ ˆ์ดํ„ฐ์˜ ์Šคํƒ์—๋„ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ

  • CPython์—์„œ ๊ธ€๋กœ๋ฒŒ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋ฝ(GIL)์€ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— Python ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๊ฑฐ๋‚˜ ์ˆ˜์ •ํ•  ๋•Œ ๋‚ด๋ถ€ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ƒํƒœ์˜ ์†์ƒ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ๋™์ผํ•œ ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ GIL์€ ๋ฆฌ์ŠคํŠธ์˜ ๊ธธ์ด(ob_size)๊ฐ€ ์ •ํ™•ํ•˜๊ฒŒ ์š”์†Œ์˜ ์ˆ˜์™€ ์ผ์น˜ํ•˜๊ณ  ๊ฐ ์š”์†Œ์˜ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ ํ•ด๋‹น ์š”์†Œ์— ๋Œ€ํ•œ ์ฐธ์กฐ ์ˆ˜๋ฅผ ์ •ํ™•ํ•˜๊ฒŒ ๋ฐ˜์˜ํ•˜๋Š” ๊ฒƒ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • GIL์ด ์—†์œผ๋ฉด์„œ ๋‹ค๋ฅธ ๋ณ€๊ฒฝ ์—†์ด ๋™์‹œ ์ˆ˜์ •์ด ๋ฐœ์ƒํ•˜๋Š” ๊ฒฝ์šฐ, ์ด๋Ÿฌํ•œ ํ•„๋“œ๊ฐ€ ์†์ƒ๋˜๊ณ  ํ”„๋กœ๊ทธ๋žจ ์ถฉ๋Œ์ด ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • GIL์€ ์—ฐ์‚ฐ์ด ์›์ž์ ์ด๊ฑฐ๋‚˜ ์—ฌ๋Ÿฌ ์—ฐ์‚ฐ์ด ๋™์‹œ์— ๋ฐœ์ƒํ•  ๋•Œ ์ •ํ™•์„ฑ์„ ์œ ์ง€ํ•˜์ง€ ์•Š๋Š”๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด, list.extend(iterable)๋Š” iterable์ด Python์œผ๋กœ ๊ตฌํ˜„๋œ ๋ฐ˜๋ณต์ž๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ๋Š” ๊ฒฝ์šฐ (๋˜๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ GIL์„ ํ•ด์ œํ•˜๋Š” ๊ฒฝ์šฐ) ์›์ž์ ์œผ๋กœ ๋ณด์ด์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  • ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, list.remove(x)๋Š” ๋ฆฌ์ŠคํŠธ๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋‹ค๋ฅธ ์ž‘์—…๊ณผ ๊ฒน์น˜๋Š” ๊ฒฝ์šฐ ์ž˜๋ชป๋œ ๊ฐ์ฒด๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด๋Š” ๋™๋“ฑ์„ฑ ์—ฐ์‚ฐ์ž์˜ ๊ตฌํ˜„์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.
  • ๊ทธ๋Ÿผ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  GIL์€ ์ผ๋ถ€ ์—ฐ์‚ฐ์ด ์‚ฌ์‹ค์ƒ ์›์ž์ ์ธ ๊ฒƒ์ฒ˜๋Ÿผ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด, ์ƒ์„ฑ์ž list(set)์€ set์˜ ํ•ญ๋ชฉ์„ ์›์ž์ ์œผ๋กœ ์ƒˆ๋กœ์šด ๋ฆฌ์ŠคํŠธ๋กœ ๋ณต์‚ฌํ•˜๋ฉฐ, ์ผ๋ถ€ ์ฝ”๋“œ๋Š” ํ•ด๋‹น ๋ณต์‚ฌ๊ฐ€ ์›์ž์ ์ž„(์ฆ‰, set์˜ ํ•ญ๋ชฉ์˜ ์Šค๋ƒ…์ƒท์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ)์„ ์˜์กดํ•ฉ๋‹ˆ๋‹ค.
  • ์ด PEP๋Š” ์ด๋Ÿฌํ•œ ์†์„ฑ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • ์ด PEP๋Š” GIL์ด ์ œ๊ณตํ•˜๋Š” ๋งŽ์€ ๋ณดํ˜ธ ๊ธฐ๋Šฅ์„ ์ œ๊ณตํ•˜๊ธฐ ์œ„ํ•ด ๊ฐœ๋ณ„ ๊ฐ์ฒด ๋ฝ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค.
  • ์˜ˆ๋ฅผ ๋“ค์–ด, ๋ชจ๋“  ๋ฆฌ์ŠคํŠธ, ์‚ฌ์ „ ๋ฐ ์ง‘ํ•ฉ์€ ๊ด€๋ จ๋œ ๊ฐ€๋ฒผ์šด ๋ฝ์„ ๊ฐ€์ง€๊ฒŒ ๋ฉ๋‹ˆ๋‹ค.
  • ๊ฐ์ฒด๋ฅผ ์ˆ˜์ •ํ•˜๋Š” ๋ชจ๋“  ์ž‘์—…์€ ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋ฝ์„ ๋ณด์œ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.
  • ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด์—์„œ ์ฝ๊ธฐ ์ž‘์—…๋„ ํ•ด๋‹น ๊ฐ์ฒด์˜ ๋ฝ์„ ํš๋“ํ•ด์•ผ ํ•˜๋ฉฐ, ๋ฝ์„ ๋ณด์œ ํ•˜์ง€ ์•Š๊ณ  ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ์ฝ๊ธฐ ์ž‘์—…์€ ์•„๋ž˜์—์„œ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.### Per-object Locking vs. GIL

๊ฐ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ž ๊ธˆ๊ณผ ํฌ๋ฆฌํ‹ฐ์ปฌ ์„น์…˜์€ GIL(Global Interpreter Lock)๋ณด๋‹ค ์•ฝํ•œ ๋ณดํ˜ธ๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. GIL์€ ๋™์‹œ ์ž‘์—…์ด ์›์ž์ ์ด๊ฑฐ๋‚˜ ์˜ฌ๋ฐ”๋ฅด๋‹ค๊ณ  ๋ณด์žฅํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๊ฐœ๋ณ„ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ž ๊ธˆ ์ฒด๊ณ„๋„ ๋™์‹œ ์ž‘์—…์ด ์›์ž์ ์ด๊ฑฐ๋‚˜ ์˜ฌ๋ฐ”๋ฅด๋‹ค๊ณ  ๋ณด์žฅํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ , ๊ฐœ๋ณ„ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ž ๊ธˆ์€ GIL๊ณผ ์œ ์‚ฌํ•œ ๋ณดํ˜ธ๋ฅผ ๋ชฉํ‘œ๋กœํ•˜์ง€๋งŒ ์ƒํ˜ธ ๋ฐฐ์ œ๋Š” ๊ฐœ๋ณ„ ๊ฐ์ฒด๋กœ ์ œํ•œ๋ฉ๋‹ˆ๋‹ค.

์ปจํ…Œ์ด๋„ˆ ์œ ํ˜•์˜ ์ธ์Šคํ„ด์Šค์— ๋Œ€ํ•œ ๋Œ€๋ถ€๋ถ„์˜ ์ž‘์—…์€ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์ž ๊ทธ๋Š” ๊ฒƒ์„ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด:

  • list.append, list.insert, list.repeat, PyList_SetItem
  • dict.setitem, PyDict_SetItem
  • list.clear, dict.clear
  • list.repr, dict.repr ๋“ฑ

list.extend(iterable)

setiter_iternext

์ผ๋ถ€ ์ž‘์—…์€ ๋‘ ๊ฐœ์˜ ์ปจํ…Œ์ด๋„ˆ ๊ฐ์ฒด์— ์ง์ ‘ ์ž‘์šฉํ•˜๋ฉฐ, ๋‘ ์ปจํ…Œ์ด๋„ˆ์˜ ๋‚ด๋ถ€ ๊ตฌ์กฐ์— ๋Œ€ํ•œ ์ •๋ณด๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, set๊ณผ ๊ฐ™์€ ํŠน์ • ๋ฐ˜๋ณต ๊ฐ€๋Šฅํ•œ ์œ ํ˜•์— ๋Œ€ํ•œ ํŠน์ˆ˜ํ™” ๋œ ๋‚ด๋ถ€์ ์ธ list.extend(iterable)์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž‘์—…์€ ๋‘ ๊ฐœ์ฒด์˜ ๋‚ด๋ถ€์— ๋™์‹œ์— ์ ‘๊ทผํ•˜๋ฏ€๋กœ ๋‘ ๊ฐœ์ฒด ๋ชจ๋‘ ์ž ๊ทธ๋Š” ๊ฒƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜์ ์ธ list.extend์˜ ๊ตฌํ˜„์€ ํ•œ ๊ฐ์ฒด (list) ๋งŒ ์ž ๊ทธ๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ฐ์ฒด๋Š” ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•œ ์ดํ„ฐ๋ ˆ์ดํ„ฐ API๋ฅผ ํ†ตํ•ด ๊ฐ„์ ‘์ ์œผ๋กœ ์•ก์„ธ์Šค๋˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ๋‘ ๊ฐœ์˜ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ž ๊ทธ๋Š” ์ž‘์—…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • list.extend(list), list.extend(set), list.extend(dictitems) ๋ฐ ์ธ์ˆ˜ ์œ ํ˜•์— ๋Œ€ํ•ด ๊ตฌํ˜„์ด ํŠน์ˆ˜ํ™” ๋œ ๋‹ค๋ฅธ ํŠน์ˆ˜ํ™”๋“ค

list.concat(list)

list.eq(list), dict.eq(dict)

์ผ๋ถ€ ๊ฐ„๋‹จํ•œ ์ž‘์—…์€ ํ•˜๋‚˜์˜ ํ•„๋“œ์—๋งŒ ์›์ž์ ์œผ๋กœ ์•ก์„ธ์Šคํ•˜์—ฌ ์ž ๊ธˆ์ด ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž‘์—…์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค.

  • len(list) ์ฆ‰, list_length(PyListObject *a)
  • len(dict)
  • len(set)

์ผ๋ถ€ ์ž‘์—…์€ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ธฐ ์œ„ํ•ด ์ž ๊ธˆํ•˜์ง€ ์•Š๊ณ  ๋‚™๊ด€์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ž‘์—…์€ ํŠน์ˆ˜ํ•œ ๊ตฌํ˜„๊ณผ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ธฐ์˜ ํ˜‘๋ ฅ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  • list[idx] (list_subscript)
  • dict[key] (dict_subscript)
  • listiter_next, dictiter_iternextkey/value/item
  • list.contains

๋Œ€์—ฌ๋œ ์ฐธ์กฐ

๊ฐœ๋ณ„ ๊ฐ์ฒด ์ž ๊ธˆ์€ GIL์ด ์ œ๊ณตํ•˜๋Š” ์ค‘์š”ํ•œ ๋ณดํ˜ธ ๊ธฐ๋Šฅ์„ ๋งŽ์ด ์ œ๊ณตํ•˜์ง€๋งŒ, ์ผ๋ถ€ ๊ฒฝ์šฐ์—๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋Œ€์—ฌ๋œ ์ฐธ์กฐ๋ฅผ "์†Œ์œ " ์ฐธ์กฐ๋กœ ์—…๊ทธ๋ ˆ์ด๋“œํ•˜๋Š” ์ฝ”๋“œ๋Š” ํŠน์ •ํ•œ ์ƒํ™ฉ์—์„œ ์•ˆ์ „ํ•˜์ง€ ์•Š์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • PyObject
    • item
  • PyList_GetItem
    • list
    • idx
  • Py_INCREF
    • item

GIL์€ ์•ก์„ธ์Šค์™€ Py_INCREF ํ˜ธ์ถœ ์‚ฌ์ด์— ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชฉ๋ก์„ ์ˆ˜์ •ํ•˜์ง€ ๋ชปํ•˜๋„๋ก ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. GIL์ด ์—†์œผ๋ฉด ๊ฐœ๋ณ„ ๊ฐ์ฒด ์ž ๊ธˆ์ด ์žˆ๋”๋ผ๋„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชฉ๋ก์„ ์ˆ˜์ •ํ•˜์—ฌ ์•ก์„ธ์Šค์™€ Py_INCREF ํ˜ธ์ถœ ์‚ฌ์ด์— item์ด ํ•ด์ œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ๊ฐ€์žˆ๋Š” ๋Œ€์—ฌ ์ฐธ์กฐ API๋Š” "์ƒˆ๋กœ์šด ์ฐธ์กฐ"๋ฅผ ๋ฐ˜ํ™˜ํ•˜์ง€๋งŒ ๊ทธ ์™ธ์—๋Š” ๋™๋“ฑํ•ฉ๋‹ˆ๋‹ค.

  • PyList_FetchItem(list, idx) : PyList_GetItem์„ ๋Œ€์ฒด
  • PyDict_FetchItem(dict, key) : PyDict_GetItem์„ ๋Œ€์ฒด
  • PyWeakref_FetchObject : PyWeakref_GetObject์„ ๋Œ€์ฒด

์ผ๋ถ€ ๋Œ€์—ฌ ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” API (์˜ˆ : PyTuple_GetItem)๋Š” ํŠœํ”Œ์ด ๋ถˆ๋ณ€์ด๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์œ„์˜ API์˜ ๋ชจ๋“  ์‚ฌ์šฉ์ด ๋ฌธ์ œ๊ฐ€๋˜๋Š” ๊ฒƒ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, PyDict_GetItem์€ ํ•จ์ˆ˜ ํ˜ธ์ถœ์—์„œ ํ‚ค์›Œ๋“œ ์ธ์ˆ˜ ์‚ฌ์ „์„ ๊ตฌ๋ฌธ ๋ถ„์„ํ•˜๋Š” ๋ฐ ์ž์ฃผ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ํ‚ค์›Œ๋“œ ์ธ์ˆ˜ ์‚ฌ์ „์€ ์‚ฌ์‹ค์ƒ ๊ฐœ์ธ์ ์ด๋ฉฐ (๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋กœ๋ถ€ํ„ฐ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Œ) ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

Python ํฌ๋ฆฌํ‹ฐ์ปฌ ์„น์…˜

์ง๊ด€์ ์ธ ๊ฐœ๋ณ„ ๊ฐ์ฒด ์ž ๊ธˆ์€ GIL๋กœ ์‹คํ–‰ํ•  ๋•Œ ์กด์žฌํ•˜์ง€ ์•Š์•˜๋˜ ๊ต์ฐฉ ์ƒํƒœ๋ฅผ ๋„์ž…ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Python ์ž‘์—…์€ ์ค‘์ฒฉ๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์Šค๋ ˆ๋“œ๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์ž‘์—…์— ๋Œ€ํ•œ ์ž ๊ธˆ (๋˜๋Š” ์ž ๊ธˆ) ๋งŒ ๋ณด์œ  ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ค‘์ฒฉ ์ž‘์—…์„ ์‹œ์ž‘ํ•˜๊ธฐ ์ „์— ์™ธ๋ถ€ ์ž‘์—…์— ๋Œ€ํ•œ ์ž ๊ธˆ์ด ์ผ์‹œ ์ค‘์ง€๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ค‘์ฒฉ ์ž‘์—…์ด ์™„๋ฃŒ๋˜๋ฉด ์™ธ๋ถ€ ์ž‘์—…์— ๋Œ€ํ•œ ์ž ๊ธˆ์„ ๋‹ค์‹œ ํš๋“ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ I/O์™€ ๊ฐ™์€ ์ž ์žฌ์ ์œผ๋กœ ๋ธ”๋กœํ‚น ์ž‘์—… (์ฆ‰, GIL์„ ํ•ด์ œ ํ•œ ์ž‘์—…) ์ฃผ์œ„์—์„œ๋„ ํ™œ์„ฑ ์ž‘์—…์— ๋Œ€ํ•œ ์ž ๊ธˆ์ด ์ผ์‹œ ์ค‘๋‹จ๋˜์–ด์•ผํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ž ๊ธˆ๊ณผ ๋ธ”๋กœํ‚น ์ž‘์—… ๊ฐ„์˜ ์ƒํ˜ธ ์ž‘์šฉ์ด ์—ฌ๋Ÿฌ ์ž ๊ธˆ๊ฐ„์˜ ์ƒํ˜ธ ์ž‘์šฉ๊ณผ ๋™์ผํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ต์ฐฉ ์ƒํƒœ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.# ๊ฐœ์š”

์ด PEP๋Š” ๋ฐ๋“œ๋ฝ์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์œ„์˜ ๋ฐฉ๋ฒ•๊ณผ ๋‹ค๋ฅธ ๋ณ€ํ˜•์„ ์ œ์•ˆํ•˜์—ฌ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ต๋‹ˆ๋‹ค. ์ค‘์ฒฉ๋œ ์ž‘์—…์ด ์‹œ์ž‘๋  ๋•Œ๋งˆ๋‹ค ์ฆ‰์‹œ ์ž ๊ธˆ์„ ์ค‘์ง€ํ•˜๋Š” ๋Œ€์‹ , ์Šค๋ ˆ๋“œ๊ฐ€ ๋ธ”๋ก๋  ๊ฒฝ์šฐ์—๋งŒ ์ž ๊ธˆ์ด ์ค‘์ง€๋ฉ๋‹ˆ๋‹ค (์ฆ‰, GIL์„ ํ•ด์ œํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค). ์ด๋ ‡๊ฒŒํ•˜๋ฉด ์ค‘์ฒฉ๋œ ์ž‘์—…์— ๋Œ€ํ•œ ์ž ๊ธˆ ํš๋“ ๋ฐ ํ•ด์ œ ํšŸ์ˆ˜๊ฐ€ ์ค„์–ด๋“ค๋ฉด์„œ ๋ฐ๋“œ๋ฝ์„ ๋ฐฉ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Python ์ž„๊ณ„ ์˜์—ญ์— ๋Œ€ํ•œ ์ œ์•ˆ๋œ API๋Š” ๋‹ค์Œ ๋„ค ๊ฐ€์ง€ ๋งคํฌ๋กœ์ž…๋‹ˆ๋‹ค. ์ด๋“ค์€ ๊ณต๊ฐœ์ ์œผ๋กœ ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ C-API ํ™•์žฅ์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ๊ณ ๋ ค๋˜์—ˆ์ง€๋งŒ ์ œํ•œ๋œ API์˜ ์ผ๋ถ€๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

Py_BEGIN_CRITICAL_SECTION(PyObject *op);

์ฐธ์กฐ ๋œ ๊ฐ์ฒด์˜ ๋ฎคํ…์Šค๋ฅผ ์–ป์–ด ์ž„๊ณ„ ์˜์—ญ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด๊ฐ€ ์ด๋ฏธ ์ž ๊ฒจ ์žˆ์œผ๋ฉด์ด ์Šค๋ ˆ๋“œ๋Š” ์ฐธ์กฐ ๋œ ๊ฐ์ฒด์˜ ์ž ๊ธˆ์ด ํ•ด์ œ ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ๋ฏธ์ฒ˜๋ฆฌ ๋œ ์ž„๊ณ„ ์˜์—ญ์˜ ์ž ๊ธˆ์ด ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค.

Py_END_CRITICAL_SECTION;

๊ฐ€์žฅ ์ตœ๊ทผ์˜ ์ž‘์—…์„ ์ข…๋ฃŒํ•˜๊ณ  ๋ฎคํ…์Šค๋ฅผ ์ž ๊ธˆ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ์œผ๋กœ ๊ฐ€์žฅ ์ตœ๊ทผ์— ์ค‘๋‹จ ๋œ ์ด์ „ ์ž„๊ณ„ ์˜์—ญ (์žˆ๋Š” ๊ฒฝ์šฐ)์ด ํ˜„์žฌ ์ค‘๋‹จ๋œ ๊ฒฝ์šฐ ๋‹ค์‹œ ์‹œ์ž‘๋ฉ๋‹ˆ๋‹ค.

Py_BEGIN_CRITICAL_SECTION2(PyObject *a, PyObject *b);

๋‘ ๊ฐœ์ฒด์˜ ๋ฎคํ…์Šค๋ฅผ ์–ป์–ด ์ž„๊ณ„ ์˜์—ญ์„ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ผ๊ด€๋œ ์ž ๊ธˆ ์ˆœ์„œ๋ฅผ ๋ณด์žฅํ•˜๊ธฐ ์œ„ํ•ด ํš๋“ ์ˆœ์„œ๋Š” ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ์— ๋”ฐ๋ผ ๊ฒฐ์ •๋ฉ๋‹ˆ๋‹ค (์ฆ‰, ๋‚ฎ์€ ๋ฉ”๋ชจ๋ฆฌ ์ฃผ์†Œ์˜ ๋ฎคํ…์Šค๊ฐ€ ๋จผ์ € ํš๋“๋จ). ๋‘ ๋ฎคํ…์Šค ์ค‘ ํ•˜๋‚˜๊ฐ€ ์ด๋ฏธ ์ž ๊ฒจ ์žˆ์œผ๋ฉด ์ฐธ์กฐ ๋œ ๊ฐœ์ฒด๊ฐ€ ์ž ๊ธˆ ํ•ด์ œ ๋  ๋•Œ๊นŒ์ง€ ๋Œ€๊ธฐํ•˜๊ธฐ ์ „์— ๋ชจ๋“  ๋ฏธ์ฒ˜๋ฆฌ ๋œ ์ž„๊ณ„ ์˜์—ญ์˜ ์ž ๊ธˆ์ด ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค.

Py_END_CRITICAL_SECTION2;

Py_END_CRITICAL_SECTION๊ณผ ๋™์ผํ•˜๊ฒŒ ์ž‘๋™ํ•˜์ง€๋งŒ ๋‘ ๊ฐœ์ฒด๋ฅผ ์ž ๊ธˆ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

๋˜ํ•œ, ์Šค๋ ˆ๋“œ๊ฐ€ ATTACHED ์ƒํƒœ์—์„œ DETACHED ์ƒํƒœ๋กœ ์ „ํ™˜ ๋  ๋•Œ ํ™œ์„ฑ ์ž„๊ณ„ ์˜์—ญ์„ ์ผ์‹œ ์ค‘์ง€ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. DETACHED์—์„œ ATTACHED๋กœ ์ „ํ™˜ ๋  ๋•Œ ๊ฐ€์žฅ ์ตœ๊ทผ์˜ ์ค‘๋‹จ ๋œ ์ž„๊ณ„ ์˜์—ญ (์žˆ๋Š” ๊ฒฝ์šฐ)์„ ๋‹ค์‹œ ์‹œ์ž‘ํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

๋‘ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋™์‹œ์— ์ž ๊ทธ๋Š” ์ž‘์—…์˜ ๊ฒฝ์šฐ Py_BEGIN_CRITICAL_SECTION2 ๋งคํฌ๋กœ๋ฅผ ์‚ฌ์šฉํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค. Py_BEGIN_CRITICAL_SECTION์„ ๋‘ ๋ฒˆ ์ค‘์ฒฉํ•˜๋Š” ๊ฒƒ๋งŒ์œผ๋กœ๋Š” ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ์ž„๊ณ„ ์˜์—ญ์€ ์™ธ๋ถ€ ์ž„๊ณ„ ์˜์—ญ์˜ ์ž ๊ธˆ์„ ํ•ด์ œ ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์ž ๊ธˆ ํšŒํ”ผ๋ฅผ ํ†ตํ•œ ์ตœ์ ํ™”

dict์™€ list์˜ ์ผ๋ถ€ ์ž‘์—…์€ ์ž ๊ธˆ์„ ํšŒํ”ผํ•ฉ๋‹ˆ๋‹ค. ์ž ๊ธˆ์„ ์–ป์ง€ ์•Š๋Š” ๋น ๋ฅธ ๊ฒฝ๋กœ ์ž‘์—…์ด ์žˆ์œผ๋ฉฐ, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ํ•ด๋‹น ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋™์‹œ์— ์ˆ˜์ •ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ํ•ด๋‹น ์‚ฌ์ „์ด๋‚˜ ๋ชฉ๋ก์˜ ์ž ๊ธˆ์„ ์–ป๋Š” ๋Š๋ฆฐ ์ž‘์—…์œผ๋กœ ์ „ํ™˜ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚™๊ด€์ ์ธ ๋น ๋ฅธ ๊ฒฝ๋กœ๊ฐ€์žˆ๋Š” ์ž‘์—…์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค.

  • PyDict_FetchItem/GetItem ๋ฐ dict.getitem
  • PyList_FetchItem/GetItem ๋ฐ list.getitem

๋˜ํ•œ, ์‚ฌ์ „๊ณผ ๋ชฉ๋ก์˜ ๋ฐ˜๋ณต์ž๋Š” ์œ„์˜ ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๋‹ค์Œ ํ•ญ๋ชฉ์„ ๋ฐ˜ํ™˜ ํ•  ๋•Œ ์ž ๊ธˆ์„ ๋‚™๊ด€์ ์œผ๋กœ ํšŒํ”ผํ•ฉ๋‹ˆ๋‹ค.

์ด๋Ÿฌํ•œ ๊ธฐ๋Šฅ์„ ์ž ๊ธˆ ํš๋“์„ ํ”ผํ•˜๊ธฐ ์œ„ํ•ด ์‚ฌ์šฉํ•˜๋Š” ์ด์œ ๋Š” ๋‘ ๊ฐ€์ง€์ž…๋‹ˆ๋‹ค. ์ฃผ์š” ์ด์œ ๋Š” ๊ฐ„๋‹จํ•œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์— ๋Œ€ํ•ด์„œ๋„ ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ์„ฑ๋Šฅ์— ํ•„์š”ํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. ์‚ฌ์ „์€ ๋ชจ๋“ˆ์˜ ์ตœ์ƒ์œ„ ํ•จ์ˆ˜ ๋ฐ ํด๋ž˜์Šค์˜ ๋ฉ”์„œ๋“œ๋ฅผ ๋ณด์œ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์‚ฌ์ „์€ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋งŽ์€ ์Šค๋ ˆ๋“œ์—์„œ ๊ณต์œ ๋˜๋Š” ํŠน์„ฑ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ ๋ฐฉ๋ฒ•๊ณผ ํ•จ์ˆ˜๋ฅผ๋กœ๋“œํ•˜๋Š” ๋ฐ ๋Œ€ํ•œ ์ด๋Ÿฌํ•œ ์ž ๊ธˆ์˜ ๊ฒฝ์Ÿ์€ ๋งŽ์€ ๊ธฐ๋ณธ ํ”„๋กœ๊ทธ๋žจ์—์„œ ํšจ์œจ์ ์ธ ํ™•์žฅ์„ ์–ต์ œ ํ•  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

์ž ๊ธˆ์„ ํ”ผํ•˜๋Š” ๋‘ ๋ฒˆ์งธ ๋™๊ธฐ๋Š” ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๊ณ  ๋‹จ์ผ ์Šค๋ ˆ๋“œ ์„ฑ๋Šฅ์„ ํ–ฅ์ƒ์‹œํ‚ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ž ๊ธˆ ํš๋“์€ ๋Œ€๋ถ€๋ถ„์˜ ์ž‘์—…์— ๋น„ํ•ด ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ๋‚ฎ์ง€๋งŒ ๋ชฉ๋ก๊ณผ ์‚ฌ์ „์˜ ๊ฐœ๋ณ„ ์š”์†Œ์— ์•ก์„ธ์Šคํ•˜๋Š” ๊ฒƒ์€ ๋น ๋ฅธ ์ž‘์—…์ž…๋‹ˆ๋‹ค (๋”ฐ๋ผ์„œ ์ž ๊ธˆ ์˜ค๋ฒ„ํ—ค๋“œ๋Š” ์ƒ๋Œ€์ ์œผ๋กœ ํฝ๋‹ˆ๋‹ค) ๋ฐ ๋นˆ๋ฒˆํ•ฉ๋‹ˆ๋‹ค (๋”ฐ๋ผ์„œ ์˜ค๋ฒ„ํ—ค๋“œ๋Š” ๋” ํฐ ์˜ํ–ฅ์„ ๋ฏธ์นฉ๋‹ˆ๋‹ค).

์ด ์„น์…˜์—์„œ๋Š” ์ž ๊ธˆ ์—†์ด ์‚ฌ์ „ ๋ฐ ๋ชฉ๋ก ์•ก์„ธ์Šค๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐ ์–ด๋ ค์›€์ด์žˆ๋Š” ๋™์‹œ์—์ด PEP์—์„œ ์ด๋Ÿฌํ•œ ๋„์ „์— ๋Œ€์‘ํ•˜๊ธฐ ์œ„ํ•ด Python ์ธํ„ฐํ”„๋ฆฌํ„ฐ์— ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค.

์ฃผ์š” ๋„์ „์€ ๋ชฉ๋ก์ด๋‚˜ ์‚ฌ์ „์—์„œ ํ•ญ๋ชฉ์„ ๊ฒ€์ƒ‰ํ•˜๊ณ  ํ•ด๋‹น ํ•ญ๋ชฉ์˜ ์ฐธ์กฐ ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๊ฒƒ์ด ์›์ž์ ์ธ ์ž‘์—…์ด ์•„๋‹ˆ๋ผ๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ํ•ญ๋ชฉ์ด ๊ฒ€์ƒ‰๋˜๊ณ  ์ฐธ์กฐ ์ˆ˜๊ฐ€ ์ฆ๊ฐ€ํ•˜๋Š” ๋™์•ˆ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ชฉ๋ก์ด๋‚˜ ์‚ฌ์ „์„ ์ˆ˜์ • ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ด์ „์— ๊ฒ€์ƒ‰ ๋œ ํ•ญ๋ชฉ์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ถ€๋ถ„์ ์ธ ์‹œ๋„๋Š” ์ฐธ์กฐ ์ˆ˜ ์ฆ๊ฐ€๋ฅผ ์กฐ๊ฑด๋ถ€ ์ฆ๊ฐ€๋กœ ๋ณ€ํ™˜ํ•˜์—ฌ ์ฐธ์กฐ ์ˆ˜๊ฐ€ 0์ด ์•„๋‹Œ ๊ฒฝ์šฐ์—๋งŒ ์ฐธ์กฐ ์ˆ˜๋ฅผ ์ฆ๊ฐ€์‹œํ‚ค๋Š” ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ด ๋ณ€๊ฒฝ์€ ์ถฉ๋ถ„ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Python ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์ˆ˜๊ฐ€ 0์ด ๋  ๋•Œ ๊ฐ์ฒด์˜ ์†Œ๋ฉธ์ž๊ฐ€ ํ˜ธ์ถœ๋˜๊ณ  ๊ฐ์ฒด๋ฅผ ์ €์žฅํ•˜๋Š” ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋‹ค๋ฅธ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋กœ ์žฌ์‚ฌ์šฉ๋˜๊ฑฐ๋‚˜ ์šด์˜ ์ฒด์ œ๋กœ ๋ฐ˜ํ™˜ ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋Œ€์‹ ,์ด PEP๋Š” ์กฐ๊ฑด๋ถ€ ์ฐธ์กฐ ์ˆ˜ ์ฆ๊ฐ€๊ฐ€ ์•ˆ์ „ํ•˜๋„๋ก ์ฐธ์กฐ ์ˆ˜ ํ•„๋“œ๊ฐ€ ์•ก์„ธ์Šคํ•˜๋Š” ๋™์•ˆ ์œ ํšจํ•˜๊ฒŒ ์œ ์ง€๋˜๋„๋กํ•˜๋Š” ๊ธฐ์ˆ ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด ๊ธฐ์ˆ ์€ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ธฐ (mimalloc)์˜ ํ˜‘๋ ฅ ๋ฐ ๋ชฉ๋ก ๋ฐ ์‚ฌ์ „ ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ํ•„์š”๋กœํ•ฉ๋‹ˆ๋‹ค. ์ œ์•ˆ ๋œ ๊ธฐ์ˆ ์€ ๋ฆฌ๋ˆ…์Šค ์ปค๋„์—์„œ ๋„๋ฆฌ ์‚ฌ์šฉ๋˜๋Š” ๋™๊ธฐํ™” ๋ฉ”์ปค๋‹ˆ์ฆ˜ ์ธ read-copy update (RCU) [6]์™€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค.# list_item ํ•จ์ˆ˜ ๊ตฌํ˜„

ํ˜„์žฌ list.getitem์„ ๊ตฌํ˜„ํ•œ C ํ•จ์ˆ˜์ธ list_item์˜ ํ˜„์žฌ ๊ตฌํ˜„ ๋ฐฉ์‹์€ ๋‹ค์Œ๊ณผ ๊ฐ™์Šต๋‹ˆ๋‹ค:

Py_INCREF(&ob_item[i]);
return ob_item[i];

์ œ์•ˆ๋œ ๊ตฌํ˜„ ๋ฐฉ์‹์€ ์กฐ๊ฑด๋ถ€ ์ฆ๊ฐ€(_Py_TRY_INCREF)๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์ถ”๊ฐ€์ ์ธ ํ™•์ธ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค:

PyObject *item = atomic_load(&ob_item[i]);
if (item || _Py_TRY_INCREF(item))
    goto retry;
if (item != atomic_load(&ob_item[i]))
    Py_DECREF(item);
    goto retry;
if (ob_item != atomic_load(&ob_item))
    Py_DECREF(item);
    goto retry;
return item;

์œ„์˜ ๋น ๋ฅด๊ณ  ๋ฝ์„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ๊ฒฝ๋กœ๊ฐ€ ์‹คํŒจํ•  ๋•Œ ๋™์‹œ ์ˆ˜์ •์œผ๋กœ ์ธํ•ด ๋ฐœ์ƒํ•˜๋Š” ์ž ๊ธด ๋Œ€์ฒด ๊ฒฝ๋กœ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” "retry" ์„œ๋ธŒ๋ฃจํ‹ด์ž…๋‹ˆ๋‹ค:

retry:
PyObject *item;
Py_BEGIN_CRITICAL_SECTION(&ob_mutex);
item = ob_item[i];
Py_INCREF(item);
Py_END_CRITICAL_SECTION(&ob_mutex);
return item;

dict ๊ตฌํ˜„์— ๋Œ€ํ•œ ์ˆ˜์ •์€ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด list์™€ dictionary ๊ฒ€์ƒ‰์˜ ๊ด€๋ จ ๋ถ€๋ถ„์€ ์•Œ๋ ค์ง„ ์ธ๋ฑ์Šค์—์„œ ๋ฐฐ์—ด์˜ ํ•ญ๋ชฉ/๊ฐ’์„ ๋กœ๋“œํ•˜๋Š” ๊ฒƒ์„ ํฌํ•จํ•˜๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

์กฐ๊ฑด๋ถ€ ์ฆ๊ฐ€๋ฅผ ๋”ฐ๋ฅด๋Š” ์ถ”๊ฐ€์ ์ธ ํ™•์ธ์€ ์ด์ „์— PyObject ๊ตฌ์กฐ์ฒด๋‚˜ list๋‚˜ dict ๋ฐฐ์—ด์„ ์ €์žฅํ•˜๋˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฆ‰์‹œ ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋„๋ก ํ—ˆ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ถ”๊ฐ€์ ์ธ ํ™•์ธ ์—†์ด ํ•จ์ˆ˜๋Š” ๋ฆฌ์ŠคํŠธ์— ์ด์ „์— ์žˆ์ง€ ์•Š์•˜๋˜ Python ๊ฐ์ฒด๋ฅผ ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด Python ๊ฐ์ฒด๊ฐ€ ์ฐจ์ง€ํ•˜๋˜ ๋ฉ”๋ชจ๋ฆฌ๋Š” ์ด์ „์— ๋ฆฌ์ŠคํŠธ์˜ ํ•ญ๋ชฉ์„ ์ €์žฅํ•˜๋˜ ๋‹ค๋ฅธ PyObject์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ €์žฅํ•˜๊ณ  ์žˆ์„ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

๋‚™๊ด€์  ๋ฆฌ์ŠคํŠธ์™€ ๋”•์…”๋„ˆ๋ฆฌ ์•ก์„ธ์Šค๋ฅผ ์œ„ํ•œ Mimalloc ๋ณ€๊ฒฝ ์‚ฌํ•ญ

์ด ๊ตฌํ˜„์€ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์ž์— ๋Œ€ํ•œ ์ถ”๊ฐ€ ์ œ์•ฝ ์กฐ๊ฑด์„ ์š”๊ตฌํ•˜๋ฉฐ, mimalloc ์ฝ”๋“œ์— ์ผ๋ถ€ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. mimalloc์˜ ๊ตฌํ˜„์— ๋Œ€ํ•œ ๋ฐฐ๊ฒฝ ์ง€์‹์€ ํ•„์š”ํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ์ดํ•ดํ•˜๋Š” ๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค. mimalloc์—์„œ ๊ฐœ๋ณ„ ํ• ๋‹น์€ "๋ธ”๋ก"์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๋ฉฐ, mimalloc "ํŽ˜์ด์ง€"๋Š” ๋ชจ๋‘ ๊ฐ™์€ ํฌ๊ธฐ์˜ ์—ฐ์†๋œ ๋ธ”๋ก์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. mimalloc "ํŽ˜์ด์ง€"๋Š” ๋‹ค๋ฅธ ํ• ๋‹น๊ธฐ์˜ "์Šˆํผ๋ธ”๋ก"๊ณผ ์œ ์‚ฌํ•˜๋ฉฐ, ์šด์˜ ์ฒด์ œ ํŽ˜์ด์ง€๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. mimalloc "ํž™"์€ ์—ฌ๋Ÿฌ ํฌ๊ธฐ ํด๋ž˜์Šค์˜ ํŽ˜์ด์ง€๋ฅผ ํฌํ•จํ•˜๋ฉฐ, ๊ฐ ํŽ˜์ด์ง€๋Š” ๋‹จ์ผ ํž™์— ์†ํ•ฉ๋‹ˆ๋‹ค. ํŽ˜์ด์ง€์˜ ๋ธ”๋ก ์ค‘ ํ•˜๋‚˜๋„ ํ• ๋‹น๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ mimalloc์€ ํŽ˜์ด์ง€๋ฅผ ๋‹ค๋ฅธ ํฌ๊ธฐ ํด๋ž˜์Šค๋‚˜ ๋‹ค๋ฅธ ํž™์— ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(์ฆ‰, ํŽ˜์ด์ง€๋ฅผ ๋‹ค์‹œ ์ดˆ๊ธฐํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).

๋ฆฌ์ŠคํŠธ์™€ ๋”•์…”๋„ˆ๋ฆฌ ์•ก์„ธ์Šค ๋ฐฉ๋ฒ•์€ mimalloc ํŽ˜์ด์ง€์˜ ์žฌ์‚ฌ์šฉ์„ ๋ถ€๋ถ„์ ์œผ๋กœ ์ œํ•œํ•˜์—ฌ ์•ก์„ธ์Šค ๊ธฐ๊ฐ„ ๋™์•ˆ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ๋ฅผ ์œ ํšจํ•œ ์ƒํƒœ๋กœ ์œ ์ง€ํ•˜๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. mimalloc ํŽ˜์ด์ง€์˜ ์ œํ•œ๋œ ์žฌ์‚ฌ์šฉ์€ Python ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋ณ„๋„์˜ ํž™์„ ๊ฐ€์ง€๊ณ  ์žˆ์Œ์œผ๋กœ์จ ๊ฐ•์ œ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ์•ก์„ธ์Šค ์ค‘์— ํ•ญ๋ชฉ์ด ํ•ด์ œ๋˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ƒˆ ๊ฐ์ฒด์— ์žฌ์‚ฌ์šฉ๋˜๋”๋ผ๋„ ์ƒˆ ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ์˜ ๋™์ผํ•œ ์œ„์น˜์— ๋ฐฐ์น˜๋ฉ๋‹ˆ๋‹ค. ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ๋Š” ํ• ๋‹น์„ ํ†ตํ•ด ์œ ํšจํ•œ ์ƒํƒœ(๋˜๋Š” 0)๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.

Py_TPFLAGS_MANAGED_DICT๋ฅผ ์ง€์›ํ•˜๋Š” Python ๊ฐ์ฒด๋Š” PyObject ํ—ค๋” ์ด์ „์— ์‚ฌ์ „ ๋ฐ ์•ฝํ•œ ์ฐธ์กฐ ํ•„๋“œ๋ฅผ ๊ฐ–๊ธฐ ๋•Œ๋ฌธ์— ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ์˜ ์˜คํ”„์…‹์ด ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ์ฒด๋Š” ๋ณ„๋„์˜ mimalloc ํž™์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, GC ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด๋Š” ์ž์ฒด ํž™์— ์ €์žฅ๋˜๋ฏ€๋กœ GC๋Š” GC ๊ฐ์ฒด๋งŒ ๊ฒ€์‚ฌํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค. ๋”ฐ๋ผ์„œ Python ๊ฐ์ฒด์—๋Š” GC ๊ฐ์ฒด๊ฐ€ ์•„๋‹Œ ๊ฐ์ฒด์šฉ ํž™, ๊ด€๋ฆฌ๋˜๋Š” ์‚ฌ์ „์ด ์žˆ๋Š” GC ๊ฐ์ฒด์šฉ ํž™, ๊ด€๋ฆฌ๋˜๋Š” ์‚ฌ์ „์ด ์—†๋Š” GC ๊ฐ์ฒด์šฉ ํž™์˜ ์„ธ ๊ฐ€์ง€ mimalloc ํž™์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Mimalloc ํŽ˜์ด์ง€ ์žฌ์‚ฌ์šฉ

์ „์ฒด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ฆ๊ฐ€์‹œํ‚ค์ง€ ์•Š๊ธฐ ์œ„ํ•ด mimalloc ํŽ˜์ด์ง€ ์žฌ์‚ฌ์šฉ์˜ ์ œํ•œ์„ ์งง์€ ์‹œ๊ฐ„์œผ๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ์œ ๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ œํ•œ์„ ๋ฆฌ์ŠคํŠธ ๋ฐ ๋”•์…”๋„ˆ๋ฆฌ ์•ก์„ธ์Šค๋กœ๋งŒ ํ•œ์ •ํ•˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์„ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ๋น„์‹ผ ๋™๊ธฐํ™”๋ฅผ ํ•„์š”๋กœ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๊ทน๋‹จ์—์„œ๋Š” ์ œํ•œ์„ ๋‹ค์Œ GC ์ฃผ๊ธฐ๊นŒ์ง€ ์œ ์ง€ํ•˜๋ฉด ์ถ”๊ฐ€ ๋™๊ธฐํ™”๋ฅผ ๋„์ž…ํ•˜์ง€ ์•Š์ง€๋งŒ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด PEP๋Š” FreeBSD์˜ "GUS"๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ ๋‘ ๊ฐ€์ง€ ๊ทน๋‹จ ์‚ฌ์ด์— ์žˆ๋Š” ์‹œ์Šคํ…œ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด ์‹œ์Šคํ…œ์€ ์ „์—ญ ๋ฐ ์Šค๋ ˆ๋“œ๋ณ„ ์นด์šดํ„ฐ(๋˜๋Š” "์‹œํ€€์Šค ๋ฒˆํ˜ธ")์˜ ์กฐํ•ฉ์„ ์‚ฌ์šฉํ•˜์—ฌ ๋นˆ mimalloc ํŽ˜์ด์ง€๋ฅผ ๋‹ค๋ฅธ ํž™์ด๋‚˜ ๋‹ค๋ฅธ ํฌ๊ธฐ ํด๋ž˜์Šค์— ์•ˆ์ „ํ•˜๊ฒŒ ์žฌ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์šด์˜ ์ฒด์ œ์— ๋ฐ˜ํ™˜ํ•  ์ˆ˜ ์žˆ๋Š” ์‹œ๊ธฐ๋ฅผ ๊ฒฐ์ •ํ•˜๋Š” ์กฐ์ •์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค:

  1. ๋‹จ์กฐ๋กœ ์ฆ๊ฐ€ํ•˜๋Š” ์ „์—ญ ์“ฐ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.
  2. mimalloc ํŽ˜์ด์ง€๊ฐ€ ๋น„์–ด ์žˆ์œผ๋ฉด ํ˜„์žฌ ์“ฐ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๋กœ ํƒœ๊ทธ๊ฐ€ ์ง€์ •๋ฉ๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ๋Š” ์ „์—ญ ์“ฐ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๋ฅผ ์›์ž์ ์œผ๋กœ ์ฆ๊ฐ€์‹œํ‚ฌ ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ๊ฐ ์Šค๋ ˆ๋“œ๋Š” ์Šค๋ ˆ๋“œ๋ณ„ ์ตœ์‹  ์“ฐ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๋ฅผ ๊ธฐ๋กํ•˜๋Š” ๋กœ์ปฌ ์ฝ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๋ฅผ ๊ฐ–์Šต๋‹ˆ๋‹ค.
  4. ์Šค๋ ˆ๋“œ๋Š” ๋ฆฌ์ŠคํŠธ ๋˜๋Š” ๋”•์…”๋„ˆ๋ฆฌ ์•ก์„ธ์Šค ์ƒํƒœ๊ฐ€ ์•„๋‹ ๋•Œ๋งˆ๋‹ค ์“ฐ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๋ฅผ ๊ด€์ฐฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ฐธ์กฐ ๊ตฌํ˜„์€ mimalloc์˜ ๋Š๋ฆฐ ๊ฒฝ๋กœ ํ• ๋‹น ํ•จ์ˆ˜์—์„œ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์œ ์šฉํ•œ ์ •๋„๋กœ ์ •๊ธฐ์ ์œผ๋กœ ํ˜ธ์ถœ๋˜์ง€๋งŒ ์ƒ๋‹นํ•œ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋„์ž…ํ•˜์ง€ ์•Š์„๋งŒํผ ์ถฉ๋ถ„ํžˆ ์ž์ฃผ ํ˜ธ์ถœ๋ฉ๋‹ˆ๋‹ค.### Global Read Sequence Number

์ „์—ญ ์ฝ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๋Š” ๋ชจ๋“  ํ™œ์„ฑ ์Šค๋ ˆ๋“œ์˜ ์ฝ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ ์ค‘ ์ตœ์†Ÿ๊ฐ’์„ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์Šค๋ ˆ๋“œ๋Š” ๋กœ์ปฌ ์ฝ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๋ฅผ ์Šค์บ”ํ•˜์—ฌ ์ „์—ญ ์ฝ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๋ฅผ ์—…๋ฐ์ดํŠธํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ƒˆ๋กœ์šด mimalloc ํŽ˜์ด์ง€๋ฅผ ํ• ๋‹นํ•˜๊ธฐ ์ „์— ์žฌ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ์ œํ•œ๋œ ํŽ˜์ด์ง€๊ฐ€ ์žˆ๋Š” ๊ฒฝ์šฐ, ์ฐธ์กฐ ๊ตฌํ˜„์€ ์ด ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค.

์ „์—ญ ์ฝ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๊ฐ€ ํŽ˜์ด์ง€์˜ ํƒœ๊ทธ ๋ฒˆํ˜ธ๋ณด๋‹ค ํฐ ๊ฒฝ์šฐ, ๋น„์–ด์žˆ๋Š” mimalloc ํŽ˜์ด์ง€๋Š” ๋‹ค๋ฅธ ํž™์ด๋‚˜ ํฌ๊ธฐ ํด๋ž˜์Šค์— ์žฌ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ „์—ญ ์ฝ๊ธฐ ์‹œํ€€์Šค ๋ฒˆํ˜ธ๊ฐ€ ํŽ˜์ด์ง€์˜ ํƒœ๊ทธ๋ณด๋‹ค ํฐ ์กฐ๊ฑด์€, ๋™์‹œ์ ์ธ ๋‚™๊ด€์ ์ธ ๋ฆฌ์ŠคํŠธ๋‚˜ ์‚ฌ์ „ ์ ‘๊ทผ์ด ์žˆ๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ํ•ด๋‹น ์ ‘๊ทผ์„ ์™„๋ฃŒํ–ˆ์Œ์„ ๋ณด์žฅํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ถฉ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ํ•ด์ œ๋œ ํŽ˜์ด์ง€์˜ ๋น„์–ด์žˆ๋Š” ๋ธ”๋ก์— ์ ‘๊ทผํ•˜๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ์—†์œผ๋ฏ€๋กœ ํ•ด๋‹น ํŽ˜์ด์ง€๋Š” ๋‹ค๋ฅธ ์šฉ๋„๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์šด์˜ ์ฒด์ œ์— ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๋‚™๊ด€์ ์ธ Dict์™€ List ์ ‘๊ทผ ์š”์•ฝ

์ด PEP๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ž ๊ธˆ์„ ํš๋“ํ•˜์ง€ ์•Š๊ณ ๋„ ์•ˆ์ „ํ•œ ๋ฆฌ์ŠคํŠธ์™€ ์‚ฌ์ „ ์ ‘๊ทผ์„ ์œ„ํ•œ ๊ธฐ์ˆ ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ํ•จ์ˆ˜์™€ ๋ฉ”์„œ๋“œ ํ˜ธ์ถœ๊ณผ ๊ฐ™์€ ์ผ๋ฐ˜์ ์ธ ์ž‘์—…์—์„œ ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๊ณ  ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ์˜ ํ™•์žฅ์„ฑ ๋ณ‘๋ชฉ ํ˜„์ƒ์„ ํ”ผํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด ์ฒด๊ณ„๋Š” ๊ฐ์ฒด๊ฐ€ ํ•ด์ œ๋œ ํ›„์—๋„ ์กฐ๊ฑด๋ถ€ ์ฐธ์กฐ ์นด์šดํŠธ ์ฆ๊ฐ€ ์ž‘์—…์ด ์•ˆ์ „ํ•˜๋„๋ก ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ ํ•„๋“œ๊ฐ€ ์œ ํšจํ•˜๊ฒŒ ์œ ์ง€๋˜๋„๋ก ์ž„์‹œ ์ œ์•ฝ ์กฐ๊ฑด์„ mimalloc ํŽ˜์ด์ง€ ์žฌ์‚ฌ์šฉ์— ์ ์šฉํ•˜์—ฌ ์ž‘๋™ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ์ œ์•ฝ ์กฐ๊ฑด์€ ๊ฐœ๋ณ„ ๊ฐ์ฒด ๋Œ€์‹  mimalloc ํŽ˜์ด์ง€์— ์ ์šฉ๋˜์–ด ๋ฉ”๋ชจ๋ฆฌ ์žฌ์‚ฌ์šฉ ๊ธฐํšŒ๋ฅผ ๊ฐœ์„ ํ•ฉ๋‹ˆ๋‹ค. ๋นˆ mimalloc ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ๋ˆ„์ ๋œ ์•ก์„ธ์Šค๊ฐ€ ์—†์Œ์„ ์‹œ์Šคํ…œ์ด ํŒ๋‹จํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒฝ์šฐ์—๋Š” ์ œ์•ฝ ์กฐ๊ฑด์ด ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ™•์ธํ•˜๊ธฐ ์œ„ํ•ด ์‹œ์Šคํ…œ์€ ๊ฐ€๋ฒผ์šด ์Šค๋ ˆ๋“œ๋ณ„ ์‹œํ€€์Šค ์นด์šดํ„ฐ์™€ ๋นˆ ํŽ˜์ด์ง€๊ฐ€ ๋˜์—ˆ์„ ๋•Œ ํŽ˜์ด์ง€์— ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ฐ ์Šค๋ ˆ๋“œ์˜ ๋กœ์ปฌ ์นด์šดํ„ฐ๊ฐ€ ํŽ˜์ด์ง€์˜ ํƒœ๊ทธ๋ณด๋‹ค ํฌ๋ฉด ํ•ด๋‹น ํŽ˜์ด์ง€๋Š” ์žฌ์‚ฌ์šฉ๋  ์ˆ˜ ์žˆ์œผ๋ฉฐ ๋‹ค๋ฅธ ๋ชฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์šด์˜ ์ฒด์ œ์— ๋ฐ˜ํ™˜๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋˜ํ•œ ์ œ์•ฝ ์กฐ๊ฑด์€ ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ๊ฐ€ ์‹คํ–‰๋  ๋•Œ๋งˆ๋‹ค ํ•ด์ œ๋ฉ๋‹ˆ๋‹ค. ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ์˜ ์Šคํ†ฑ-๋”-์›”๋“œ ์ผ์‹œ ์ •์ง€๋ฅผ ํ†ตํ•ด ์Šค๋ ˆ๋“œ๊ฐ€ ๋น„์–ด์žˆ๋Š” mimalloc ํŽ˜์ด์ง€์— ๋Œ€ํ•œ ๋ฏธ๊ฒฐ๋œ ์ฐธ์กฐ๋ฅผ ๊ฐ€์ง€๊ณ  ์žˆ์ง€ ์•Š์Œ์ด ๋ณด์žฅ๋ฉ๋‹ˆ๋‹ค.

ํŠนํ™”๋œ ์ธํ„ฐํ”„๋ฆฌํ„ฐ

ํŠนํ™”๋œ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” GIL ์—†์ด ์‹คํ–‰๋  ๋•Œ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜๋„๋ก ๋ช‡ ๊ฐ€์ง€ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

  • ๋ฎคํ…์Šค๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์ผํ•œ ์ธ๋ผ์ธ ์บ์‹œ์— ์“ฐ๋Š” ๊ฒƒ์„ ๋ฐฉ์ง€ํ•˜์—ฌ ๋™์‹œ ํŠนํ™”๋ฅผ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
  • GIL์ด ์—†๋Š” ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์—์„œ๋Š” ๊ฐ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๊ฐ€ ํ•œ ๋ฒˆ๋งŒ ํŠนํ™”๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์Šค๋ ˆ๋“œ๊ฐ€ ๋ถ€๋ถ„์ ์œผ๋กœ ์ž‘์„ฑ๋œ ์ธ๋ผ์ธ ์บ์‹œ๋ฅผ ์ฝ์ง€ ๋ชปํ•˜๋„๋กํ•ฉ๋‹ˆ๋‹ค.
  • ๋ฝ์„ ์‚ฌ์šฉํ•˜์—ฌ tp_version_tag ๋ฐ keys_version์˜ ์บ์‹œ๋œ ๊ฐ’์ด ์บ์‹œ๋œ ๋””์Šคํฌ๋ฆฝํ„ฐ ๋ฐ ๊ธฐํƒ€ ๊ฐ’๊ณผ ์ผ์น˜ํ•˜๋„๋กํ•ฉ๋‹ˆ๋‹ค.
  • ์ธ๋ผ์ธ ์นด์šดํ„ฐ์— ๋Œ€ํ•œ ์ˆ˜์ •์€ "relaxed atomics"๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์ผ๋ถ€ ์นด์šดํ„ฐ ๊ฐ์†Œ๊ฐ€ ๋ˆ„๋ฝ๋˜๊ฑฐ๋‚˜ ๋ฎ์–ด์“ฐ์—ฌ๋„ ์ •ํ™•์„ฑ์—๋Š” ์˜ํ–ฅ์„ ๋ฏธ์น˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Py_mod_gil ์Šฌ๋กฏ

--disable-gil ๋นŒ๋“œ์—์„œ ํ™•์žฅ์„ ๋กœ๋“œํ•  ๋•Œ, CPython์€ ์ƒˆ๋กœ์šด PEP 489 ์Šคํƒ€์ผ์˜ Py_mod_gil ์Šฌ๋กฏ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์Šฌ๋กฏ์ด Py_mod_gil_not_used๋กœ ์„ค์ •๋œ ๊ฒฝ์šฐ, ํ™•์žฅ ๋กœ๋”ฉ์€ ์ผ๋ฐ˜์ ์œผ๋กœ ์ง„ํ–‰๋ฉ๋‹ˆ๋‹ค. ์Šฌ๋กฏ์ด ์„ค์ •๋˜์ง€ ์•Š์€ ๊ฒฝ์šฐ, ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋ฅผ ์ผ์‹œ ์ •์ง€์‹œํ‚ค๊ณ  GIL์„ ํ™œ์„ฑํ™”ํ•œ ํ›„ ๊ณ„์† ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ, ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” GIL์ด ํ™œ์„ฑํ™”๋˜์—ˆ์Œ์„ ์•Œ๋ฆฌ๋Š” ๊ฐ€์‹œ์ ์ธ ๊ฒฝ๊ณ ๋ฅผ ๋ฐœ์ƒ์‹œํ‚ค๊ณ  ์‚ฌ์šฉ์ž๊ฐ€ ์ด๋ฅผ ๋ฌด์‹œํ•  ์ˆ˜ ์žˆ๋Š” ๋‹จ๊ณ„๋ฅผ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค.

PYTHONGIL ํ™˜๊ฒฝ ๋ณ€์ˆ˜

--disable-gil ๋นŒ๋“œ์—์„œ ์‚ฌ์šฉ์ž๋Š” ์‹คํ–‰ ์ค‘์— ๋™์ž‘์„ ์žฌ์ •์˜ํ•˜๊ธฐ ์œ„ํ•ด PYTHONGIL ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋ฅผ ์„ค์ •ํ•  ์ˆ˜๋„ ์žˆ์Šต๋‹ˆ๋‹ค. PYTHONGIL=0์œผ๋กœ ์„ค์ •ํ•˜๋ฉด ๋ชจ๋“ˆ ์Šฌ๋กฏ ๋กœ์ง์„ ๋ฌด์‹œํ•˜๊ณ  GIL์„ ๋น„ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค. PYTHONGIL=1๋กœ ์„ค์ •ํ•˜๋ฉด GIL์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

PYTHONGIL=0 ์žฌ์ •์˜๋Š” GIL์ด ์—†์–ด๋„ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ํ™•์žฅ์ด ์—ฌ์ „ํžˆ ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ์œ ์šฉํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ™•์žฅ์„ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ์—์„œ๋งŒ ์‚ฌ์šฉํ•˜๊ฑฐ๋‚˜ ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•˜์—ฌ ์•ก์„ธ์Šค๋ฅผ ๋ณดํ˜ธํ•  ์ˆ˜ ์žˆ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฏธ GIL์ด ์žˆ๋Š” ์ƒํƒœ์—์„œ๋„ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๋ช‡ ๊ฐ€์ง€ ํ™•์žฅ์ด ์žˆ์œผ๋ฉฐ, ์‚ฌ์šฉ์ž๋Š” ์ด๋ฏธ ์ด๋Ÿฌํ•œ ์œ ํ˜•์˜ ์กฐ์น˜๋ฅผ ์ทจํ•ด์•ผํ•ฉ๋‹ˆ๋‹ค.

PYTHONGIL=1 ์žฌ์ •์˜๋Š” ๋•Œ๋•Œ๋กœ ๋””๋ฒ„๊น…์— ์œ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋น„์„ธ๋Œ€ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘

์ด PEP๋Š” GIL์ด ์—†๋Š” CPython์—์„œ ์„ธ๋Œ€๋ณ„ ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ์—์„œ ๋น„์„ธ๋Œ€ ์ˆ˜์ง‘๊ธฐ๋กœ ์ „ํ™˜ํ•˜๋Š” ๊ฒƒ์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ํ•˜๋‚˜์˜ ์„ธ๋Œ€ (์ฆ‰, "old" ์„ธ๋Œ€)๋งŒ ๊ฐ€์ง€๋Š” ๊ฒƒ๊ณผ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. ์ด ์ œ์•ˆ๋œ ๋ณ€๊ฒฝ์„ ์œ„ํ•ด ๋‘ ๊ฐ€์ง€ ์ด์œ ๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค.### ์‚ฌ์ดํด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜๊ณผ ๋‹ค์ค‘ ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์˜ ํ™•์žฅ์„ฑ

์‚ฌ์ดํด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์€ ์ Š์€ ์„ธ๋Œ€์—์„œ๋„ ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๋ฅผ ์ผ์‹œ ์ค‘์ง€ํ•ด์•ผํ•œ๋‹ค. ์ €์ž๋Š” ์ Š์€ ์„ธ๋Œ€์˜ ๋นˆ๋ฒˆํ•œ ์ปฌ๋ ‰์…˜์œผ๋กœ ์ธํ•ด ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ”„๋กœ๊ทธ๋žจ์˜ ํšจ์œจ์ ์ธ ํ™•์žฅ์„ฑ์ด ์ €ํ•˜๋  ์ˆ˜ ์žˆ๋‹ค๋Š” ์šฐ๋ ค๋ฅผ ํ‘œ๋ช…ํ•˜๊ณ  ์žˆ๋‹ค. ์ด๊ฒƒ์€ ์ Š์€ ์„ธ๋Œ€์— ํ•ด๋‹นํ•˜๋Š” ์‚ฌ์ดํด ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ๋ฟ๋งŒ ์•„๋‹ˆ๋ผ, ์˜ค๋ž˜๋œ ์„ธ๋Œ€์˜ ์ปฌ๋ ‰์…˜์—๋Š” ํ•ด๋‹นํ•˜์ง€ ์•Š๋Š”๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ Š์€ ์„ธ๋Œ€๋Š” ์ผ์ •ํ•œ ํ• ๋‹น ํšŸ์ˆ˜ ํ›„์— ์ปฌ๋ ‰์…˜๋˜๊ธฐ ๋•Œ๋ฌธ์—, ์˜ค๋ž˜๋œ ์„ธ๋Œ€์˜ ์ปฌ๋ ‰์…˜์€ ํž™์— ์žˆ๋Š” ๋ผ์ด๋ธŒ ๊ฐ์ฒด์˜ ๊ฐœ์ˆ˜์— ๋น„๋ก€ํ•˜์—ฌ ์˜ˆ์•ฝ๋œ๋‹ค. ๋˜ํ•œ, GIL ์—†์ด ๊ฐ ์„ธ๋Œ€์˜ ๊ฐ์ฒด๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ถ”์ ํ•˜๋Š” ๊ฒƒ์€ ์–ด๋ ต๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ˜„์žฌ CPython์€ ๊ฐ ์„ธ๋Œ€์— ๋Œ€ํ•œ ๊ฐ์ฒด๋“ค์˜ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. CPython์ด ์ด๋Ÿฌํ•œ ์„ค๊ณ„๋ฅผ ์œ ์ง€ํ•˜๋ ค๋ฉด, ํ•ด๋‹น ๋ฆฌ์ŠคํŠธ๋“ค์„ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“ค์–ด์•ผํ•˜๋Š”๋ฐ, ์ด๋ฅผ ํšจ์œจ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ ๋ถ„๋ช…ํ•˜์ง€ ์•Š๋‹ค.

๋‹ค๋ฅธ ๋งŽ์€ ์–ธ์–ด ๋Ÿฐํƒ€์ž„์—์„œ๋Š” ์„ธ๋Œ€๋ณ„ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์„ ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ๋งŽ์€ Java HotSpot ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ ๊ตฌํ˜„์€ ์—ฌ๋Ÿฌ ์„ธ๋Œ€๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค. ์ด๋Ÿฐ ๋Ÿฐํƒ€์ž„์—์„œ๋Š” ์ Š์€ ์„ธ๋Œ€๊ฐ€ ์ž์ฃผ ์ฒ˜๋ฆฌ๋˜์–ด ์„ฑ๋Šฅ ํ–ฅ์ƒ์„ ์ด๋Œ์–ด๋‚ธ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ Š์€ ์„ธ๋Œ€์˜ ๋งŽ์€ ๋น„์œจ์ด ์ผ๋ฐ˜์ ์œผ๋กœ "์ฃฝ์€" ๊ฐ์ฒด์ด๊ธฐ ๋•Œ๋ฌธ์—, GC๋Š” ์ˆ˜ํ–‰ํ•œ ์ž‘์—…์— ๋น„ํ•ด ๋งŽ์€ ์–‘์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํšŒ์ˆ˜ํ•  ์ˆ˜ ์žˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์—ฌ๋Ÿฌ Java ๋ฒค์น˜๋งˆํฌ๋Š” "์ Š์€" ๊ฐ์ฒด ์ค‘ 90% ์ด์ƒ์ด ์ผ๋ฐ˜์ ์œผ๋กœ ์ˆ˜์ง‘๋œ๋‹ค๊ณ  ๋ณด์—ฌ์ค€๋‹ค. ์ด๊ฒƒ์€ ์ผ๋ฐ˜์ ์œผ๋กœ "์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค"์ด๋ผ๊ณ  ๋ถˆ๋ฆฌ๋ฉฐ, ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด๊ฐ€ ์–ด๋ฆด ๋•Œ ์ฃฝ๋Š”๋‹ค๋Š” ๊ด€์ฐฐ์„ ์˜๋ฏธํ•œ๋‹ค. CPython์—์„œ๋Š” ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์ด๋Ÿฌํ•œ ํŒจํ„ด์ด ๋ฐ˜๋Œ€๋กœ ๋‚˜ํƒ€๋‚œ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด๋Š” ์—ฌ์ „ํžˆ ์–ด๋ฆด ๋•Œ ์ฃฝ์ง€๋งŒ, ํ•ด๋‹น ๊ฐ์ฒด์˜ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0์ด ๋  ๋•Œ ์ˆ˜์ง‘๋œ๋‹ค. ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์ฃผ๊ธฐ๊นŒ์ง€ ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด๋Š” ๋Œ€๋ถ€๋ถ„ ๊ณ„์† ์‚ด์•„์žˆ์„ ๊ฐ€๋Šฅ์„ฑ์ด ๋†’๋‹ค. ์ด ์ฐจ์ด๋กœ ์ธํ•ด CPython์—์„œ๋Š” ๋‹ค๋ฅธ ๋งŽ์€ ์–ธ์–ด ๋Ÿฐํƒ€์ž„๋ณด๋‹ค ์„ธ๋Œ€๋ณ„ ์ปฌ๋ ‰์…˜์ด ํ›จ์”ฌ ํšจ๊ณผ์ ์ด์ง€ ์•Š๋‹ค.

dict ๋ฐ list ์ ‘๊ทผ์—์„œ์˜ ๋‚™๊ด€์ ์ธ ๋ฝ ํšŒํ”ผ

์ด ์ œ์•ˆ์€ ๋ฆฌ์ŠคํŠธ์™€ ๋”•์…”๋„ˆ๋ฆฌ์˜ ๊ฐœ๋ณ„ ์š”์†Œ์— ์ ‘๊ทผํ•  ๋•Œ ๋Œ€๋ถ€๋ถ„์˜ ๊ฒฝ์šฐ ๋ฝ(๋ฎคํ…์Šค)์„ ํš๋“ํ•˜๋Š” ๊ฒƒ์„ ํ”ผํ•˜๋Š” ๋ฐฉ์‹์— ์˜์กดํ•œ๋‹ค. ์ด๋Š” "๋ฝ ํ”„๋ฆฌ(lock-free)" ์•Œ๊ณ ๋ฆฌ์ฆ˜๊ณผ "์›จ์ดํŠธ ํ”„๋ฆฌ(wait-free)" ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์˜๋ฏธ์—์„œ๋Š” "๋ฝ ํ”„๋ฆฌ"๊ฐ€ ์•„๋‹ˆ๋‹ค. ๊ทธ์ € ์ผ๋ฐ˜์ ์ธ ๊ฒฝ์šฐ์— ๋ฝ(๋ฎคํ…์Šค)์„ ํš๋“ํ•˜์ง€ ์•Š๋„๋ก ํ•˜์—ฌ ๋ณ‘๋ ฌ์„ฑ์„ ํ–ฅ์ƒ์‹œํ‚ค๊ณ  ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ด๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค.

ํ›จ์”ฌ ๋” ๊ฐ„๋‹จํ•œ ๋Œ€์•ˆ์€ ๋”•์…”๋„ˆ๋ฆฌ์™€ ๋ฆฌ์ŠคํŠธ ์ ‘๊ทผ์„ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌ๋”-๋ผ์ดํ„ฐ ๋ฝ์„ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ๋ฆฌ๋”-๋ผ์ดํ„ฐ ๋ฝ์€ ๋™์‹œ์— ์ฝ์„ ์ˆ˜๋Š” ์žˆ์ง€๋งŒ ์—…๋ฐ์ดํŠธ๋Š” ํ•  ์ˆ˜ ์—†๋Š” ๊ธฐ๋Šฅ์„ ๊ฐ€์ง€๊ณ  ์žˆ์–ด ๋”•์…”๋„ˆ๋ฆฌ์™€ ๋ฆฌ์ŠคํŠธ์— ์ด์ƒ์ ์œผ๋กœ ๋ณด์ผ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋ฆฌ๋”-๋ผ์ดํ„ฐ ๋ฝ์€ ์ƒ๋‹นํ•œ ์˜ค๋ฒ„ํ—ค๋“œ์™€ ํ™•์žฅ์„ฑ์ด ๋–จ์–ด์ง„๋‹ค๋Š” ๋ฌธ์ œ์ ์ด ์žˆ๋‹ค. ํŠนํžˆ ๋‹จ์ผ ์š”์†Œ์— ๋Œ€ํ•œ ๋”•์…”๋„ˆ๋ฆฌ์™€ ๋ฆฌ์ŠคํŠธ ์ ‘๊ทผ๊ณผ ๊ฐ™์ด ํฌ๋ฆฌํ‹ฐ์ปฌ ์„น์…˜์ด ์ž‘์€ ๊ฒฝ์šฐ์— ๊ทธ๋ ‡๋‹ค. ๋ฆฌ๋”์˜ ํ™•์žฅ์„ฑ์ด ๋–จ์–ด์ง€๋Š” ์ด์œ ๋Š” pthread_rwlock์˜ ๋ฆฌ๋” ์ˆ˜๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•˜๋Š” ๊ฒƒ๊ณผ ๊ฐ™์€ ๋™์ผํ•œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ์—…๋ฐ์ดํŠธํ•ด์•ผ ํ•˜๋Š”๋ฐ์—์„œ ๋น„๋กฏ๋œ๋‹ค.

์ด PEP์— ์„ค๋ช…๋œ ๊ธฐ์ˆ ์€ RCU(Read-Copy-Update; ์ฝ๊ธฐ-๋ณต์‚ฌ-๊ฐฑ์‹ )์™€, ๋” ์ ์€ ์ •๋„๋กœ ํ•˜์ž๋“œ ํฌ์ธํ„ฐ(hazard pointers)์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค. RCU๋Š” ํ™•์žฅ ๊ฐ€๋Šฅํ•œ ๋ฐฉ์‹์œผ๋กœ ๊ณต์œ  ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ๋ฅผ ๋ณดํ˜ธํ•˜๊ธฐ ์œ„ํ•ด ๋ฆฌ๋”๊ฐ€ ๋™์‹œ์— ์—…๋ฐ์ดํŠธ๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ฒฝ์šฐ์— ๋„๋ฆฌ ์‚ฌ์šฉ๋œ๋‹ค. ์ด PEP์˜ ๊ธฐ์ˆ ๊ณผ RCU๋Š” ๋ชจ๋‘ ๋™์‹œ ๋ฐ์ดํ„ฐ ๊ตฌ์กฐ์— ์ ‘๊ทผํ•˜๋Š” ๋™์•ˆ ํšŒ์ˆ˜๋ฅผ ์—ฐ๊ธฐํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ์ž‘๋™ํ•œ๋‹ค. RCU๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ํ•ด์‹œ ํ…Œ์ด๋ธ”์ด๋‚˜ ์—ฐ๊ฒฐ ๋ฆฌ์ŠคํŠธ์™€ ๊ฐ™์€ ๊ฐœ๋ณ„ ๊ฐ์ฒด๋ฅผ ๋ณดํ˜ธํ•˜๋Š” ๋ฐ ์‚ฌ์šฉ๋˜์ง€๋งŒ, ์ด PEP์—์„œ๋Š” mimalloc "ํŽ˜์ด์ง€"์™€ ๊ฐ™์€ ํฐ ๋ฉ”๋ชจ๋ฆฌ ๋ธ”๋ก์„ ๋ณดํ˜ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ œ์•ˆํ•œ๋‹ค.

์ด๋Ÿฌํ•œ ๊ธฐ์ˆ ์˜ ํ•„์š”์„ฑ์€ ์ฃผ๋กœ CPython์—์„œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. CPython์ด ์ถ”์  ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒฝ์šฐ๋ผ๋ฉด ์ด๋Ÿฌํ•œ ๊ธฐ์ˆ ์ด ํ•„์š”ํ•˜์ง€ ์•Š์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์™œ๋ƒํ•˜๋ฉด ์ถ”์  ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ๋Š” ์ด๋ฏธ ํ•„์š”ํ•œ ๋ฐฉ์‹์œผ๋กœ ํšŒ์ˆ˜๋ฅผ ์—ฐ๊ธฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค. ์ด๋Ÿฌํ•œ ์ ‘๊ทผ์€ ํ™•์žฅ์„ฑ ๋ฌธ์ œ๋ฅผ "ํ•ด๊ฒฐ"ํ•˜์ง€๋Š” ์•Š์ง€๋งŒ, ๋งŽ์€ ์–ด๋ ค์›€์„ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ ๊ตฌํ˜„์œผ๋กœ ์ „ํ™˜ํ•  ๊ฒƒ์ด๋‹ค.

์—ญํ˜ธํ™˜์„ฑ

์ด PEP๋Š” CPython์„ --disable-gil ํ”Œ๋ž˜๊ทธ๋กœ ๋นŒ๋“œํ•  ๋•Œ ์ผ๋ถ€ ์—ญํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋ฅผ ์•ผ๊ธฐํ•˜์ง€๋งŒ, ๊ธฐ๋ณธ ๋นŒ๋“œ ๊ตฌ์„ฑ์„ ์‚ฌ์šฉํ•  ๋•Œ๋Š” ์ด๋Ÿฌํ•œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜์ง€ ์•Š๋Š”๋‹ค. ๊ฑฐ์˜ ๋ชจ๋“  ์—ญํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋Š” C-API์™€ ๊ด€๋ จ์ด ์žˆ๋‹ค.

GIL ์—†์ด CPython์„ ๋นŒ๋“œํ•˜๋ฉด ํ‘œ์ค€ CPython ๋นŒ๋“œ๋‚˜ ์•ˆ์ •์ ์ธ ABI์™€ ABI ํ˜ธํ™˜์„ฑ์ด ์—†์–ด์ง€๋ฏ€๋กœ biased reference counting์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด Python ๊ฐ์ฒด ํ—ค๋”์— ๋Œ€ํ•œ ๋ณ€๊ฒฝ์ด ํ•„์š”ํ•˜๋‹ค.
์ด ๋ฒ„์ „์— ๋งž๋Š” C-API ํ™•์žฅ์„ ๋…๋ฆฝ์ ์œผ๋กœ ๋‹ค์‹œ ๋นŒ๋“œํ•ด์•ผ ํ•œ๋‹ค.

GIL์„ ์‚ฌ์šฉํ•˜์—ฌ C ์ฝ”๋“œ์—์„œ ์ „์—ญ ์ƒํƒœ๋‚˜ ๊ฐ์ฒด ์ƒํƒœ๋ฅผ ๋ณดํ˜ธํ•˜๋Š” C-API ํ™•์žฅ์€ GIL ์—†์ด ์‹คํ–‰๋  ๋•Œ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ์ถ”๊ฐ€์ ์ธ ๋ช…์‹œ์  ๋ฝ์ด ํ•„์š”ํ•˜๋‹ค.

GIL ์—†์ด ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ๋ฐฉ์‹์œผ๋กœ borrowed references๋ฅผ ์‚ฌ์šฉํ•˜๋Š” C-API ํ™•์žฅ์€ ๋น„๋Œ€์นญ๋œ ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์ƒˆ๋กœ์šด ๋™๋“ฑํ•œ API๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค. borrowed references์˜ ์‚ฌ์šฉ ์ค‘ ์ผ๋ถ€๋งŒ ๋ฌธ์ œ๊ฐ€ ๋˜๋Š”๋ฐ, ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ์—์„œ ํ•ด์ œ๋  ์ˆ˜ ์žˆ๋Š” ๊ฐ์ฒด์— ๋Œ€ํ•œ ์ฐธ์กฐ๋งŒ ๋ฌธ์ œ๊ฐ€ ๋œ๋‹ค.# Custom Memory Allocators

์š”์•ฝ

  • ์‚ฌ์šฉ์ž ์ •์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ธฐ(PyMem_SetAllocator)๋Š” ์‹ค์ œ ํ• ๋‹น์„ ์ด์ „์— ์„ค์ •๋œ ํ• ๋‹น๊ธฐ์— ์œ„์ž„ํ•ด์•ผํ•œ๋‹ค.
  • Python ๊ฐ์ฒด๋Š” PyType_GenericNew ๋˜๋Š” PyObject_Malloc๊ณผ ๊ฐ™์€ ํ‘œ์ค€ API๋ฅผ ํ†ตํ•ด ํ• ๋‹น๋˜์–ด์•ผ ํ•œ๋‹ค.
  • Python ์ฝ”๋“œ์˜ ์—ญํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๋Š” ์ƒ๋Œ€์ ์œผ๋กœ ์ ๋‹ค.
  • Python ๋ฐฐํฌ์— ์ƒˆ๋กœ์šด ๋„์ „์ด ์ œ๊ธฐ๋œ๋‹ค.
  • ์„ฑ๋Šฅ์— ์˜ํ–ฅ์„ ๋ฏธ์นœ๋‹ค.
  • ๋นŒ๋“œ ๋ด‡์— ํฌํ•จ๋œ๋‹ค.
  • ์‚ฌ์šฉ ๋ฐฉ๋ฒ•์„ ๊ฐ€๋ฅด์น˜๋Š” ๋ฐฉ๋ฒ•์ด ํฌํ•จ๋œ๋‹ค.
  • ์ฐธ์กฐ ๊ตฌํ˜„์ด ์žˆ๋‹ค.
  • ๋Œ€์ฒด ๋ฐฉ์•ˆ์ด ์žˆ๋‹ค.

์‚ฌ์šฉ์ž ์ •์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ธฐ

Python์—์„œ๋Š” ์‚ฌ์šฉ์ž ์ •์˜ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ธฐ(PyMem_SetAllocator)๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‹ค์ œ ํ• ๋‹น์„ ์ด์ „์— ์„ค์ •๋œ ํ• ๋‹น๊ธฐ์— ์œ„์ž„ํ•ด์•ผ ํ•œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, Python ๋””๋ฒ„๊ทธ ํ• ๋‹น๊ธฐ์™€ ์ถ”์  ํ• ๋‹น๊ธฐ๋Š” ํ• ๋‹น์„ ๊ธฐ๋ณธ ํ• ๋‹น๊ธฐ์— ์œ„์ž„ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๊ณ„์† ์ž‘๋™ํ•œ๋‹ค. ๋ฐ˜๋ฉด์—, ํ• ๋‹น๊ธฐ๋ฅผ ์™„์ „ํžˆ ๋Œ€์ฒดํ•˜๋Š” ๊ฒƒ(jemalloc ๋˜๋Š” tcmalloc๊ณผ ๊ฐ™์€)์€ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ์ž‘๋™ํ•˜์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

Python ๊ฐ์ฒด๋Š” PyType_GenericNew ๋˜๋Š” PyObject_Malloc์™€ ๊ฐ™์€ ํ‘œ์ค€ API๋ฅผ ํ†ตํ•ด ํ• ๋‹น๋˜์–ด์•ผ ํ•œ๋‹ค. ๋น„-Python ๊ฐ์ฒด๋Š” ์ด๋Ÿฌํ•œ API๋ฅผ ํ†ตํ•ด ํ• ๋‹น๋˜์–ด์„œ๋Š” ์•ˆ๋œ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ํ˜„์žฌ๋Š” ๋ฒ„ํผ(non-Python ๊ฐ์ฒด)๋ฅผ PyObject_Malloc์„ ํ†ตํ•ด ํ• ๋‹นํ•˜๋Š” ๊ฒƒ์ด ํ—ˆ์šฉ๋˜์ง€๋งŒ, ์ด์ œ๋Š” ํ—ˆ์šฉ๋˜์ง€ ์•Š๊ณ  ๋Œ€์‹  PyMem_Malloc, PyMem_RawMalloc ๋˜๋Š” malloc์„ ํ†ตํ•ด ๋ฒ„ํผ๋ฅผ ํ• ๋‹นํ•ด์•ผ ํ•œ๋‹ค.

Python ์ฝ”๋“œ์—๋Š” ๋” ์ ์€ ์—ญํ˜ธํ™˜์„ฑ ๋ฌธ์ œ๊ฐ€ ์žˆ๋‹ค:

  • ์ฝ”๋“œ ๊ฐ์ฒด์™€ ์ตœ์ƒ์œ„ ํ•จ์ˆ˜ ๊ฐ์ฒด์— ๋Œ€ํ•œ ์†Œ๋ฉธ์ž์™€ ์•ฝํ•œ ์ฐธ์กฐ ์ฝœ๋ฐฑ์€ ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŒ…์„ ์‚ฌ์šฉํ•˜์—ฌ ๋‹ค์Œ ์ˆœํ™˜ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊นŒ์ง€ ์ง€์—ฐ๋œ๋‹ค.
  • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ์•ก์„ธ์Šคํ•˜๋Š” ์ผ๋ถ€ ๊ฐ์ฒด์˜ ์†Œ๋ฉธ์ž๋Š” ์ฐธ์กฐ ์นด์šดํŒ…์— ํŽธํ–ฅ์ด ์ ์šฉ๋˜์–ด ์•ฝ๊ฐ„ ์ง€์—ฐ๋  ์ˆ˜ ์žˆ๋‹ค. ์ด๋Š” ๋“œ๋ฌผ๋‹ค: ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด, ์‹ฌ์ง€์–ด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ์•ก์„ธ์Šคํ•˜๋Š” ๊ฐ์ฒด๋„ ์ฐธ์กฐ ์นด์šดํŠธ๊ฐ€ 0์ด ๋˜๋Š” ์ฆ‰์‹œ ํŒŒ๊ดด๋œ๋‹ค. Python ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ํ…Œ์ŠคํŠธ์˜ ๋‘ ๊ณณ์€ gc.collect() ํ˜ธ์ถœ์ด ๊ณ„์† ํ†ต๊ณผํ•˜๊ธฐ ์œ„ํ•ด ํ•„์š”ํ•˜๋‹ค.

๋ฐฐํฌ

์ด PEP๋Š” Python ๋ฐฐํฌ์— ์ƒˆ๋กœ์šด ๋„์ „์„ ์ œ๊ธฐํ•œ๋‹ค. ์–ด์จŒ๋“ , ๋ณ„๋„๋กœ ์ปดํŒŒ์ผ๋œ C-API ํ™•์žฅ์ด ํ•„์š”ํ•œ ๋‘ ๊ฐ€์ง€ ๋ฒ„์ „์˜ Python์ด ์กด์žฌํ•˜๊ฒŒ ๋  ๊ฒƒ์ด๋‹ค. C-API ํ™•์žฅ ์ž‘์„ฑ์ž๊ฐ€ --disable-gil๊ณผ ํ˜ธํ™˜๋˜๋Š” ํŒจํ‚ค์ง€๋ฅผ ๋นŒ๋“œํ•˜๊ณ  PyPI์— ์—…๋กœ๋“œํ•˜๋Š” ๋ฐ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ๋˜ํ•œ, ์–ด๋–ค ์ž‘์„ฑ์ž๋“ค์€ --disable-gil ๋ชจ๋“œ๋ฅผ ๋„๋ฆฌ ์‚ฌ์šฉํ•˜๊ธฐ ์ „๊นŒ์ง€ ์ง€์›์„ ๋ง์„ค์ผ ์ˆ˜ ์žˆ์ง€๋งŒ, ์‚ฌ์šฉ ๊ฐ€๋Šฅํ•œ Python์˜ ๋‹ค์–‘ํ•œ ํ™•์žฅ ๊ธฐ๋Šฅ์— ๋”ฐ๋ผ ์‚ฌ์šฉ์ด ๋‹ฌ๋ผ์งˆ ๊ฒƒ์ด๋‹ค.

์ด๋ฅผ ์™„ํ™”ํ•˜๊ธฐ ์œ„ํ•ด, ์ €์ž๋Š” Anaconda์™€ ํ˜‘๋ ฅํ•˜์—ฌ --disable-gil ๋ฒ„์ „์˜ Python์„ conda ์ฑ„๋„๋กœ๋ถ€ํ„ฐ ํ˜ธํ™˜๋˜๋Š” ํŒจํ‚ค์ง€์™€ ํ•จ๊ป˜ ๋ฐฐํฌํ•  ๊ณ„ํš์ด๋‹ค. ์ด๋ ‡๊ฒŒ ํ•˜๋ฉด ํ™•์žฅ ๊ธฐ๋Šฅ์„ ๋นŒ๋“œํ•˜๋Š” ๋ฌธ์ œ๋ฅผ ์ค‘์•™์ง‘์ค‘ํ™”ํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ, ์ €์ž๋Š” ์ด๋ฅผ ํ†ตํ•ด ์‚ฌ๋žŒ๋“ค์ด GIL ์—†์ด ๋” ๋นจ๋ฆฌ Python์„ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์ด๋ผ๊ณ  ๋ฏฟ๋Š”๋‹ค.

์„ฑ๋Šฅ

GIL ์—†์ด CPython์„ ์Šค๋ ˆ๋“œ ์•ˆ์ „ํ•˜๊ฒŒ ๋งŒ๋“œ๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ --disable-gil ๋นŒ๋“œ์˜ ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค. ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ์˜ ์˜ํ–ฅ์€ ๋‹จ์ผ ์Šค๋ ˆ๋“œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ๊ณผ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ ์‚ฌ์ด์—์„œ ๋‹ค๋ฅด๋ฏ€๋กœ, ์•„๋ž˜ ํ‘œ๋Š” ๊ฐ๊ฐ์˜ ํ”„๋กœ๊ทธ๋žจ ์œ ํ˜•์— ๋Œ€ํ•œ ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ๋”ฐ๋กœ ๋ณด๊ณ ํ•œ๋‹ค.

pyperformance 1.0.6์—์„œ์˜ ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ

  • ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ: 6%
  • ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ: 8%

์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ธก์ •ํ•˜๊ธฐ ์œ„ํ•ด 3.12 ๋ฒ„์ „์˜ Python์—์„œ PR 19474์˜ 018be4c๋ฅผ ๊ธฐ์ค€์œผ๋กœ ์‚ฌ์šฉ๋˜์—ˆ๋‹ค. ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ์˜ ๊ฐ€์žฅ ํฐ ๊ธฐ์—ฌ๋Š” ํŽธํ–ฅ ์ฐธ์กฐ ์นด์šดํŒ…์ด๋ฉฐ, ๊ทธ ๋‹ค์Œ์œผ๋กœ๋Š” ๊ฐœ๋ณ„ ๊ฐ์ฒด ์ž ๊ธˆ์ด ๋”ฐ๋ฅธ๋‹ค. ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์„ ์œ„ํ•ด, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ ์‹คํ–‰๋˜๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ์€ ํŠน์ • ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋ฅผ ํ•œ ๋ฒˆ๋งŒ ํŠน์ˆ˜ํ™”ํ•œ๋‹ค. ์ด๊ฒƒ์ด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์˜ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ๋ณด๋‹ค ํฐ ์ด์œ ์ด๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ GIL์ด ๋น„ํ™œ์„ฑํ™”๋œ ์ƒํƒœ์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์€ CPU ์ฝ”์–ด๋ฅผ ๋” ํšจ๊ณผ์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•œ๋‹ค.

์ด PEP๋Š” CPython์˜ ๊ธฐ๋ณธ(๋น„ --disable-gil) ๋นŒ๋“œ์˜ ์„ฑ๋Šฅ์—๋Š” ์˜ํ–ฅ์„ ์ฃผ์ง€ ์•Š๋Š”๋‹ค.

๋นŒ๋“œ ๋ด‡

์•ˆ์ •์ ์ธ ๋นŒ๋“œ ๋ด‡์—๋Š” --disable-gil ๋นŒ๋“œ๊ฐ€ ํฌํ•จ๋œ๋‹ค.

์‚ฌ์šฉ ๋ฐฉ๋ฒ• ๊ฐ€๋ฅด์น˜๊ธฐ

--disable-gil ๋ชจ๋“œ๋ฅผ ๊ตฌํ˜„ํ•˜๋Š” ์ผํ™˜์œผ๋กœ, ์ €์ž๋Š” GIL ์—†์ด Python์„ ์‹คํ–‰ํ•  ๋•Œ ํ˜ธํ™˜๋˜๋Š” ํŒจํ‚ค์ง€๋ฅผ ๋งŒ๋“ค๊ธฐ ์œ„ํ•œ "HOWTO" ๊ฐ€์ด๋“œ๋ฅผ ์ž‘์„ฑํ•  ๊ฒƒ์ด๋‹ค.

์ฐธ์กฐ ๊ตฌํ˜„

GIL ์—†๋Š” CPython์˜ ๋ฒ„์ „์„ ๊ตฌํ˜„ํ•œ ๋‘ ๊ฐœ์˜ GitHub ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๊ฐ€ ์žˆ๋‹ค:

nogil-3.12์€ Python 3.12.0a4๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค. ์ด๊ฒƒ์€ ๋‹จ์ผ ์Šค๋ ˆ๋“œ ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ํ‰๊ฐ€ํ•˜๊ณ  ์ด PEP์˜ ์ฐธ์กฐ ๊ตฌํ˜„์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ์— ์œ ์šฉํ•˜๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ๋งŽ์€ ํ™•์žฅ์ด ํ˜„์žฌ Python 3.12๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— C-API ํ™•์žฅ ํ˜ธํ™˜์„ฑ์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐ๋Š” ๊ทธ๋‹ค์ง€ ์œ ์šฉํ•˜์ง€ ์•Š๋‹ค. 3.12 ํฌํŠธ์— ์ œํ•œ๋œ ์‹œ๊ฐ„์œผ๋กœ ์ธํ•ด nogil-3.12 ๊ตฌํ˜„์€ ๋ชจ๋“  ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ๊ฑด๋„ˆ๋›ฐ์ง€ ์•Š๋Š”๋‹ค. ์ผ์‹œ์ ์ธ ํ•ด๊ฒฐ์ฑ…์œผ๋กœ, ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์ƒ์„ฑํ•˜๋Š” ํ”„๋กœ๊ทธ๋žจ์—์„œ ์ง€์—ฐ๋œ ์ฐธ์กฐ ์นด์šดํŠธ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ๋ถˆ๋ฉธ ๊ฐ์ฒด๋กœ ๋งŒ๋“ ๋‹ค.

nogil ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋Š” Python 3.9.10์„ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค. ์‹ค์ œ ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ๊ณผ ํ™•์žฅ ํ˜ธํ™˜์„ฑ์—์„œ ๋‹ค์ค‘ ์Šค๋ ˆ๋”ฉ ํ™•์žฅ์„ฑ์„ ํ‰๊ฐ€ํ•˜๋Š” ๋ฐ ์œ ์šฉํ•˜๋‹ค. nogil-3.12 ๋ฆฌํฌ์ง€ํ† ๋ฆฌ๋ณด๋‹ค ์•ˆ์ •์ ์ด๊ณ  ํ…Œ์ŠคํŠธ๊ฐ€ ์ž˜ ๋˜์—ˆ๋‹ค.

๋Œ€์ฒด ๋ฐฉ์•ˆ

Python์€ ํ˜„์žฌ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋ฅผ ๊ฐ€๋Šฅํ•˜๊ฒŒ ํ•˜๋Š” ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ง€์›ํ•˜์ง€๋งŒ, ๊ธฐ์กด ๊ธฐ์ˆ ์—๋Š” ์ค‘์š”ํ•œ ์ œํ•œ ์‚ฌํ•ญ์ด ์žˆ๋‹ค.

  • Multiprocessing# ๋Œ€์ฒด ๋ฐฉ๋ฒ•

ํŒŒ์ด์ฌ์€ ํ˜„์žฌ ๋ณ‘๋ ฌ์„ฑ์„ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ์—ฌ๋Ÿฌ ๊ฐ€์ง€ ๋ฐฉ๋ฒ•์„ ์ œ๊ณตํ•˜์ง€๋งŒ ๊ธฐ์กด ๊ธฐ์ˆ ์—๋Š” ์ค‘์š”ํ•œ ์ œ์•ฝ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค.

Multiprocessing

multiprocessing ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ํŒŒ์ด์ฌ ํ”„๋กœ๊ทธ๋žจ์—์„œ ํŒŒ์ด์ฌ ์„œ๋ธŒํ”„๋กœ์„ธ์Šค๋ฅผ ์‹œ์ž‘ํ•˜๊ณ  ํ†ต์‹ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๊ฐ ์„œ๋ธŒํ”„๋กœ์„ธ์Šค๋Š” ์ž์ฒด ํŒŒ์ด์ฌ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ๊ฐ€์ง€๊ธฐ ๋•Œ๋ฌธ์— ๋ณ‘๋ ฌ์„ฑ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค(์ฆ‰, ํ”„๋กœ์„ธ์Šค๋งˆ๋‹ค GIL์ด ์žˆ์Šต๋‹ˆ๋‹ค). ๊ทธ๋Ÿฌ๋‚˜ multiprocessing์€ ๋ช‡ ๊ฐ€์ง€ ์ œ์•ฝ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์„ธ์Šค ๊ฐ„ ํ†ต์‹ ์ด ์ œํ•œ๋ฉ๋‹ˆ๋‹ค. ๊ฐ์ฒด๋Š” ์ผ๋ฐ˜์ ์œผ๋กœ ์ง๋ ฌํ™”๋˜์–ด ๊ณต์œ  ๋ฉ”๋ชจ๋ฆฌ๋กœ ๋ณต์‚ฌ๋˜์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ์˜ค๋ฒ„ํ—ค๋“œ(์ง๋ ฌํ™”๋กœ ์ธํ•œ)๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ multiprocessing ์œ„์— API๋ฅผ ๊ตฌ์ถ•ํ•˜๋Š” ๊ฒƒ์„ ๋ณต์žกํ•˜๊ฒŒ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์„œ๋ธŒํ”„๋กœ์„ธ์Šค ์‹œ์ž‘ ๋น„์šฉ๋„ ์Šค๋ ˆ๋“œ ์‹œ์ž‘ ๋น„์šฉ๋ณด๋‹ค ๋†’์Šต๋‹ˆ๋‹ค. ํŠนํžˆ "spawn" ๊ตฌํ˜„์—์„œ๋Š” ์Šค๋ ˆ๋“œ ์‹œ์ž‘์— ์•ฝ 100ยตs๊ฐ€ ๊ฑธ๋ฆฌ์ง€๋งŒ, ์„œ๋ธŒํ”„๋กœ์„ธ์Šค ์‹œ์ž‘์—๋Š” ์•ฝ 50ms(50,000ยตs)๊ฐ€ ๊ฑธ๋ฆฝ๋‹ˆ๋‹ค. ๋งˆ์ง€๋ง‰์œผ๋กœ, ๋งŽ์€ C ๋ฐ C++ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ์—์„œ์˜ ์ ‘๊ทผ์„ ์ง€์›ํ•˜์ง€๋งŒ ์—ฌ๋Ÿฌ ํ”„๋กœ์„ธ์Šค์—์„œ์˜ ์ ‘๊ทผ์ด๋‚˜ ์‚ฌ์šฉ์€ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

C-API ํ™•์žฅ์—์„œ GIL ํ•ด์ œ

C-API ํ™•์žฅ์€ ๊ธด ์‹คํ–‰ ์‹œ๊ฐ„ ํ•จ์ˆ˜ ์ฃผ์œ„์—์„œ GIL์„ ํ•ด์ œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” GIL์ด ํ•ด์ œ๋˜๋ฉด ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์–ด๋Š ์ •๋„์˜ ๋ณ‘๋ ฌ์„ฑ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, GIL ํš๋“ ๋ฐ ํ•ด์ œ์˜ ์˜ค๋ฒ„ํ—ค๋“œ๋กœ ์ธํ•ด ์ด๋Š” ๋ช‡ ๊ฐœ์˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋„˜์–ด์„œ๋Š” ํšจ์œจ์ ์œผ๋กœ ํ™•์žฅ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋งŽ์€ ๊ณผํ•™ ๊ณ„์‚ฐ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๊ณ„์‚ฐ ์ง‘์•ฝ์ ์ธ ํ•จ์ˆ˜์—์„œ GIL์„ ํ•ด์ œํ•˜๋ฉฐ, CPython ํ‘œ์ค€ ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋Š” ๋ธ”๋กœํ‚น I/O ์ฃผ์œ„์—์„œ GIL์„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

๋‚ด๋ถ€ ๋ณ‘๋ ฌํ™”

C๋กœ ๊ตฌํ˜„๋œ ํ•จ์ˆ˜๋Š” ๋‚ด๋ถ€์ ์œผ๋กœ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, ์ธํ…”์˜ NumPy ๋ฐฐํฌํŒ, PyTorch ๋ฐ TensorFlow๋Š” ๋ชจ๋‘ ์ด ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•˜์—ฌ ๊ฐœ๋ณ„ ์ž‘์—…์„ ๋‚ด๋ถ€์ ์œผ๋กœ ๋ณ‘๋ ฌํ™”ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Š” ๊ธฐ๋ณธ ์ž‘์—…์ด ํšจ์œจ์ ์œผ๋กœ ๋ณ‘๋ ฌํ™”ํ•˜๊ธฐ์— ์ถฉ๋ถ„ํžˆ ํฐ ๊ฒฝ์šฐ์—๋Š” ์ž˜ ์ž‘๋™ํ•˜์ง€๋งŒ, ๋งŽ์€ ์ž‘์€ ์ž‘์—…์ด ์žˆ๋Š” ๊ฒฝ์šฐ๋‚˜ ์ž‘์—…์ด ์ผ๋ถ€ Python ์ฝ”๋“œ์— ์˜์กดํ•˜๋Š” ๊ฒฝ์šฐ์—๋Š” ์ž‘๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. C์—์„œ Python์„ ํ˜ธ์ถœํ•˜๋ ค๋ฉด GIL์„ ํš๋“ํ•ด์•ผ ํ•˜๋ฏ€๋กœ, Python ์ฝ”๋“œ์˜ ์งง์€ ์ฝ”๋“œ ์Šค๋‹ˆํŽซ์กฐ์ฐจ ํ™•์žฅ์„ฑ์„ ์ œํ•œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ด€๋ จ๋œ ์ž‘์—…

์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ณ„ GIL

์ตœ๊ทผ ์Šน์ธ๋œ PEP 684์€ ๋ฉ€ํ‹ฐ์ฝ”์–ด ๋ณ‘๋ ฌ์„ฑ์„ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ณ„ GIL์„ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋™์ผํ•œ ํ”„๋กœ์„ธ์Šค ๋‚ด์˜ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๊ฐ„์— ๋ณ‘๋ ฌ์„ฑ์ด ๊ฐ€๋Šฅํ•˜์ง€๋งŒ, ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๊ฐ„์— ํŒŒ์ด์ฌ ๋ฐ์ดํ„ฐ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๋ฐ๋Š” ์ƒ๋‹นํ•œ ์ œ์•ฝ ์‚ฌํ•ญ์ด ์žˆ์Šต๋‹ˆ๋‹ค. ์ด PEP๊ณผ PEP 684์€ ๋ชจ๋‘ ๋ฉ€ํ‹ฐ์ฝ”์–ด ๋ณ‘๋ ฌ์„ฑ์„ ๋‹ค๋ฃจ์ง€๋งŒ, ๋‹ค๋ฅธ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„์™€ ๊ธฐ์ˆ ์„ ๊ฐ€์ง€๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. CPython์—์„œ ๋™์‹œ์— ์ด ๋‘ ๊ฐ€์ง€ PEP์„ ๊ตฌํ˜„ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€๋Šฅํ•ฉ๋‹ˆ๋‹ค.

Gilectomy

Gilectomy [20]๋Š” GIL์„ CPython์—์„œ ์ œ๊ฑฐํ•˜๊ธฐ ์œ„ํ•œ Larry Hastings์˜ ํ”„๋กœ์ ํŠธ์˜€์Šต๋‹ˆ๋‹ค. ์ด PEP์—์„œ ์ œ์•ˆ๋œ ๋””์ž์ธ๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ Gilectomy๋Š” ๋™์ผํ•œ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋‚ด์—์„œ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์‹คํ–‰๋˜๋Š” ๊ฒƒ(์ฆ‰, "free-threading")์„ ์ง€์›ํ•˜๋ฉฐ, ์„ธ๋ฐ€ํ•˜๊ฒŒ ๋ถ„ํ• ๋œ ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด PEP์˜ ์ฐธ์กฐ ๊ตฌํ˜„์€ Gilectomy์™€ ๋น„๊ตํ•˜์—ฌ ๋‹จ์ผ ์Šค๋ ˆ๋“œ ์„ฑ๋Šฅ๊ณผ ํ™•์žฅ์„ฑ์„ ๊ฐœ์„ ํ–ˆ์Šต๋‹ˆ๋‹ค.

PyParallel

PyParallel [21]์€ Trent Nelson์— ์˜ํ•ด Python 3.3์˜ ๊ฐœ๋… ์ฆ๋ช…์šฉ ํฌํฌ๋กœ, ๋‹จ์ผ Python ํ”„๋กœ์„ธ์Šค์—์„œ ๋™์‹œ์— ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์ง€์›ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด ํฌํฌ๋Š” "๋ณ‘๋ ฌ ์Šค๋ ˆ๋“œ"๋ผ๋Š” ๊ฐœ๋…์„ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ฃผ ์Šค๋ ˆ๋“œ๊ฐ€ ์ผ์‹œ ์ค‘์ง€๋œ ๋™์•ˆ ๋ณ‘๋ ฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋  ์ˆ˜ ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ณ‘๋ ฌ ์Šค๋ ˆ๋“œ๋Š” ์ฃผ ์Šค๋ ˆ๋“œ์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด์— ๋Œ€ํ•ด ์ฝ๊ธฐ ์ „์šฉ ์•ก์„ธ์Šค ๊ถŒํ•œ์„ ๊ฐ–๊ณ  ์žˆ์—ˆ์Šต๋‹ˆ๋‹ค. ๋ณ‘๋ ฌ ์Šค๋ ˆ๋“œ์—์„œ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋Š” ์ƒ์„ฑํ•œ ์Šค๋ ˆ๋“œ์˜ ์ˆ˜๋ช… ๋™์•ˆ ์ง€์†๋˜์—ˆ์Šต๋‹ˆ๋‹ค. HTTP ์„œ๋ฒ„์˜ ๊ฒฝ์šฐ, ์ด๋Š” ์š”์ฒญ์˜ ์ˆ˜๋ช…๊ณผ ์ผ์น˜ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

python-safethread

python-safethread [22] ํ”„๋กœ์ ํŠธ๋Š” Adam Olsen์— ์˜ํ•ด Python 3.0์— ๋Œ€ํ•œ ํŒจ์น˜๋กœ GIL์„ ์ œ๊ฑฐํ•˜๋Š” ๊ฒƒ์ด์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ํ”„๋กœ์ ํŠธ์˜ ์ผ๋ถ€๋Š” ์ด PEP์—์„œ ์ œ์•ˆ๋œ ๋””์ž์ธ๊ณผ ์œ ์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๋‘˜ ๋‹ค ์„ธ๋ฐ€ํ•œ ์ž ๊ธˆ์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ๊ฐœ์ฒด๊ฐ€ ๋™์ผํ•œ ์Šค๋ ˆ๋“œ์—์„œ ์ƒ์„ฑ๋˜๊ณ  ์•ก์„ธ์Šค๋˜๋Š” ๊ฒฝ์šฐ๋ฅผ ์œ„ํ•ด ์ฐธ์กฐ ์นด์šดํŒ…์„ ์ตœ์ ํ™”ํ•ฉ๋‹ˆ๋‹ค.

Greg Stein์˜ Free-Threading ํŒจ์น˜

1996๋…„, Greg Stein์€ Python 1.4์— ๋Œ€ํ•œ GIL์„ ์ œ๊ฑฐํ•˜๋Š” ํŒจ์น˜๋ฅผ ๊ฒŒ์‹œํ–ˆ์Šต๋‹ˆ๋‹ค [23]. ์ด ํŒจ์น˜๋Š” Windows์—์„œ ์›์ž์ ์ธ ์ฐธ์กฐ ์นด์šดํŒ…๊ณผ Linux์—์„œ ์ „์—ญ ์ฐธ์กฐ ์นด์šดํŠธ ์ž ๊ธˆ์„ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ๋ฆฌ์ŠคํŠธ์™€ ๋”•์…”๋„ˆ๋ฆฌ ์•ก์„ธ์Šค๋Š” ๋ฎคํ…์Šค๋กœ ๋ณดํ˜ธ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด ํŒจ์น˜์˜ ์ผ๋ถ€๋Š” CPython์—์„œ ์ฑ„ํƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, ์ด ํŒจ์น˜๋Š” PyThreadState ๊ตฌ์กฐ์ฒด์™€ ์˜ฌ๋ฐ”๋ฅธ ์Šค๋ ˆ๋“œ๋ณ„ ์˜ˆ์™ธ ์ฒ˜๋ฆฌ๋ฅผ ๋„์ž…ํ–ˆ์Šต๋‹ˆ๋‹ค.

Dave Beazley๋Š” 2011๋…„ ๋ธ”๋กœ๊ทธ ๊ฒŒ์‹œ๋ฌผ์—์„œ ์ด ํŒจ์น˜๋ฅผ ๋‹ค์‹œ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค [24].

Jython ๋ฐ IronPython

Jython [25] ๋ฐ IronPython [26]๊ณผ ๊ฐ™์€ ๋Œ€์ฒด ํŒŒ์ด์ฌ ๊ตฌํ˜„์€ ์ „์—ญ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ์ž ๊ธˆ(GIL)์„ ๊ฐ–๊ณ  ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๊ทธ๋Ÿฌ๋‚˜ ์ด๋“ค์€ CPython ํ™•์žฅ์„ ์ง€์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. (์ด ๊ตฌํ˜„์€ Java ๋˜๋Š” C#์œผ๋กœ ์ž‘์„ฑ๋œ ์ฝ”๋“œ์™€ ์ƒํ˜ธ ์ž‘์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค).

PyPy-STM

pypy-stm [27] ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋Š” ์†Œํ”„ํŠธ์›จ์–ด ํŠธ๋žœ์žญ์…˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” PyPy์˜ ๋ณ€ํ˜•์ž…๋‹ˆ๋‹ค. ์ €์ž๋“ค์€ PyPy์™€์˜ ๋‹จ์ผ ์Šค๋ ˆ๋“œ ์„ฑ๋Šฅ ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ 20%~50% ๋ฒ”์œ„์— ์žˆ๋‹ค๊ณ  ๋ณด๊ณ ํ–ˆ์Šต๋‹ˆ๋‹ค. ์ด๋Š” CPython ํ™•์žฅ๊ณผ ํ˜ธํ™˜๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ฑฐ์ ˆ๋œ ์•„์ด๋””์–ด

์™œ ๋™์‹œ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„๊นŒ์š”?# ๊ฑฐ๋ถ€๋œ ์•„์ด๋””์–ด

๋™์‹œ์„ฑ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ 

๋งŽ์€ ์ตœ๊ทผ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ๋Š” ์ฃผ๋กœ ๋™์‹œ์„ฑ์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๋™์‹œ์— ๊ฐ€๋น„์ง€ ์ˆ˜์ง‘๊ธฐ๋ฅผ ์‹คํ–‰ํ•˜์—ฌ ๊ธด ์ •์ง€ ์‹œ๊ฐ„์„ ํ”ผํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์™œ ๋™์‹œ์„ฑ ์ˆ˜์ง‘๊ธฐ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„๊นŒ์š”?

๋™์‹œ ์ˆ˜์ง‘์€ ์“ฐ๊ธฐ ๋ฐ”๋ฆฌ์–ด(๋˜๋Š” ์ฝ๊ธฐ ๋ฐ”๋ฆฌ์–ด)๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. CPython์— ์“ฐ๊ธฐ ๋ฐ”๋ฆฌ์–ด๋ฅผ ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์€ C-API๋ฅผ ์ƒ๋‹นํžˆ ๋ง๊ฐ€ํŠธ๋ฆฌ์ง€ ์•Š๊ณ  ์ถ”๊ฐ€ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ €์ž๋Š” ์•Œ์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค.

PyDict_GetItem์„ PyDict_FetchItem์œผ๋กœ ๋Œ€์ฒดํ•˜์ง€ ์•Š๋Š” ์ด์œ 

์ด PEP๋Š” PyDict_GetItem๊ณผ ๋™์ผํ•˜๊ฒŒ ๋™์ž‘ํ•˜์ง€๋งŒ ๋Œ€์ถœ๋œ ์ฐธ์กฐ ๋Œ€์‹  ์ƒˆ๋กœ์šด ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” PyDict_FetchItem์ด๋ผ๋Š” ์ƒˆ๋กœ์šด API๋ฅผ ์ œ์•ˆํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์ถœ๋œ ์ฐธ์กฐ์— ๋Œ€ํ•œ ๊ธฐ์ˆ ์—์„œ ์„ค๋ช…ํ•œ ๋Œ€๋กœ GIL์ด ์—†๋Š” ์ƒํƒœ์—์„œ ์‹คํ–‰ํ•  ๋•Œ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ ์ผ๋ถ€ ๋Œ€์ถœ๋œ ์ฐธ์กฐ ์‚ฌ์šฉ์„ PyDict_FetchItem๊ณผ ๊ฐ™์€ ํ•จ์ˆ˜๋กœ ๋Œ€์ฒดํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด PEP์€ ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋ช‡ ๊ฐ€์ง€ ์ด์œ ๋กœ PyDict_GetItem ๋ฐ ๋Œ€์ถœ๋œ ์ฐธ์กฐ๋ฅผ ๋ฐ˜ํ™˜ํ•˜๋Š” ์œ ์‚ฌํ•œ ํ•จ์ˆ˜๋ฅผ ํ์ง€ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

  • ๋Œ€์ถœ๋œ ์ฐธ์กฐ์˜ ๋งŽ์€ ์‚ฌ์šฉ์€ GIL์ด ์—†๋Š” ์ƒํƒœ์—์„œ ์‹คํ–‰ํ•  ๋•Œ๋„ ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด, C API ํ•จ์ˆ˜๋Š” ํ‚ค์›Œ๋“œ ์ธ์ˆ˜ ์‚ฌ์ „์—์„œ ํ•ญ๋ชฉ์„ ๊ฒ€์ƒ‰ํ•˜๊ธฐ ์œ„ํ•ด PyDict_GetItem์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ํ˜ธ์ถœ์€ ํ‚ค์›Œ๋“œ ์ธ์ˆ˜ ์‚ฌ์ „์ด ๋‹จ์ผ ์Šค๋ ˆ๋“œ์—๋งŒ ํ‘œ์‹œ๋˜๊ธฐ ๋•Œ๋ฌธ์— ์•ˆ์ „ํ•ฉ๋‹ˆ๋‹ค.
  • ์ €์ž๋Š” ์ดˆ๊ธฐ์— ์ด ์ ‘๊ทผ ๋ฐฉ์‹์„ ์‹œ๋„ํ•ด ๋ณด์•˜๊ณ , PyDict_GetItem์„ PyDict_FetchItem์œผ๋กœ ๋Œ€๋ถ€๋ถ„ ๊ต์ฒดํ•˜๋ฉด ์ฐธ์กฐ ๊ณ„์‚ฐ ๋ฒ„๊ทธ๊ฐ€ ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์„ ์•Œ๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ œ ์˜๊ฒฌ์œผ๋กœ๋Š” ์ฐธ์กฐ ๊ณ„์‚ฐ ๋ฒ„๊ทธ๋ฅผ ๋„์ž…ํ•  ์œ„ํ—˜์€ ์ผ๋ฐ˜์ ์œผ๋กœ GIL์ด ์—†๋Š” ์ƒํƒœ์—์„œ ์•ˆ์ „ํ•˜์ง€ ์•Š์€ PyDict_GetItem ํ˜ธ์ถœ์„ ๋†“์น˜๋Š” ์œ„ํ—˜๋ณด๋‹ค ๋” ํฌ๋‹ค๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค.

PEP 683 ๋ถˆ๋ฉธํ™” ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” ์ด์œ 

PEP 683๊ณผ ๋งˆ์ฐฌ๊ฐ€์ง€๋กœ, ์ด PEP๋Š” Python ๊ฐ์ฒด์— ๋Œ€ํ•œ ๋ถˆ๋ฉธํ™” ์ฒด๊ณ„๋ฅผ ์ œ์•ˆํ•˜์ง€๋งŒ, ๋ถˆ๋ฉธ ๊ฐ์ฒด๋ฅผ ํ‘œ์‹œํ•˜๊ธฐ ์œ„ํ•ด PEP์—์„œ ์‚ฌ์šฉํ•˜๋Š” ๋น„ํŠธ ํ‘œํ˜„์€ ๋‹ค๋ฆ…๋‹ˆ๋‹ค. ์ด PEP๋Š” ๋‘ ๊ฐœ์˜ ์ฐธ์กฐ ๊ณ„์ˆ˜ ํ•„๋“œ ๋Œ€์‹  ํ•˜๋‚˜์˜ ์ฐธ์กฐ ๊ณ„์ˆ˜ ํ•„๋“œ๋ฅผ ๊ฐ€์ง„ ๊ฒฝํ–ฅ ์žˆ๋Š” ์ฐธ์กฐ ๊ณ„์ˆ˜์— ์˜์กดํ•˜๊ธฐ ๋•Œ๋ฌธ์— ๋™์ผํ•œ ์ฒด๊ณ„์ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๊ฐœ์„ ๋œ ํŠน์ˆ˜ํ™”

Python 3.11 ๋ฆด๋ฆฌ์Šค์—์„œ ๋น ๋ฅธ CPython ํ”„๋กœ์ ํŠธ์˜ ์ผ๋ถ€๋กœ์„œ ํ€ต๋‹๊ณผ ํŠน์ˆ˜ํ™”๊ฐ€ ๋„์ž…๋˜์–ด ์„ฑ๋Šฅ์ด ํฌ๊ฒŒ ํ–ฅ์ƒ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ํŠน์ˆ˜ํ™”๋Š” ๋Š๋ฆฐ ๋ฐ”์ดํŠธ ์ฝ”๋“œ ๋ช…๋ น์„ ๋น ๋ฅธ ๋ณ€ํ˜•์œผ๋กœ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค [19]. ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์‘์šฉ ํ”„๋กœ๊ทธ๋žจ(๋ฐ GIL ์—†์ด ์‹คํ–‰๋˜๋Š”)์˜ ์Šค๋ ˆ๋“œ ์•ˆ์ „์„ฑ์„ ์œ ์ง€ํ•˜๊ธฐ ์œ„ํ•ด ๊ฐ ๋ฐ”์ดํŠธ ์ฝ”๋“œ๋Š” ํ•œ ๋ฒˆ๋งŒ ํŠน์ˆ˜ํ™”๋ฉ๋‹ˆ๋‹ค. ์ด๋Š” ์ผ๋ถ€ ํ”„๋กœ๊ทธ๋žจ์—์„œ ์„ฑ๋Šฅ์„ ์ €ํ•˜์‹œํ‚ฌ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์—ฌ๋Ÿฌ ๋ฒˆ ํŠน์ˆ˜ํ™”ํ•˜๋Š” ๊ฒƒ์„ ์ง€์›ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ, ์ด๋Š” ์ถ”๊ฐ€ ์กฐ์‚ฌ๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ ์ด PEP์˜ ์ผ๋ถ€๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

Python ๋นŒ๋“œ ๋ชจ๋“œ

์ด PEP๋Š” ํ‘œ์ค€ ๋นŒ๋“œ ๋ชจ๋“œ์™€ ABI ํ˜ธํ™˜๋˜์ง€ ์•Š๋Š” ์ƒˆ๋กœ์šด ๋นŒ๋“œ ๋ชจ๋“œ(--disable-gil)๋ฅผ ๋„์ž…ํ•ฉ๋‹ˆ๋‹ค. ์ถ”๊ฐ€ ๋นŒ๋“œ ๋ชจ๋“œ๋Š” Python ์ฝ”์–ด ๊ฐœ๋ฐœ์ž์™€ ํ™•์žฅ ๊ฐœ๋ฐœ์ž ์–‘์ชฝ์— ๋ณต์žก์„ฑ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์ €์ž๋Š” ์ด๋Ÿฌํ•œ ๋นŒ๋“œ ๋ชจ๋“œ๋ฅผ ๊ฒฐํ•ฉํ•˜๊ณ  ์ „์—ญ ์ธํ„ฐํ”„๋ฆฌํ„ฐ ๋ฝ์„ ๋Ÿฐํƒ€์ž„์—์„œ ์ œ์–ดํ•˜๋ฉฐ ๊ธฐ๋ณธ์ ์œผ๋กœ ๋น„ํ™œ์„ฑํ™”ํ•˜๋Š” ๊ฒƒ์ด ๊ฐ€์น˜ ์žˆ๋Š” ๋ชฉํ‘œ๋ผ๊ณ  ์ƒ๊ฐํ•ฉ๋‹ˆ๋‹ค. ์ด ๋ชฉํ‘œ๋ฅผ ์œ„ํ•œ ๊ฒฝ๋กœ๋Š” ์—ฌ์ „ํžˆ ์—ด๋ฆฐ ๋ฌธ์ œ์ด์ง€๋งŒ, ๊ฐ€๋Šฅํ•œ ๊ฒฝ๋กœ๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

  • 2024๋…„, CPython 3.13์ด --disable-gil ๋นŒ๋“œ ํƒ€์ž„ ํ”Œ๋ž˜๊ทธ๋ฅผ ์ง€์›ํ•˜๋Š” ๊ฒƒ์œผ๋กœ ์ถœ์‹œ๋ฉ๋‹ˆ๋‹ค. CPython์—๋Š” GIL์ด ์žˆ๋Š” ABI์™€ GIL์ด ์—†๋Š” ABI ๋‘ ๊ฐ€์ง€๊ฐ€ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™•์žฅ ๊ฐœ๋ฐœ์ž๋Š” ๋‘ ๊ฐ€์ง€ ABI๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•ฉ๋‹ˆ๋‹ค.

  • 2

    3๊ฐœ์˜ ๋ฆด๋ฆฌ์Šค ํ›„(์ฆ‰, 2026๋…„

    2027๋…„), CPython์ด ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋‚˜ ํ”Œ๋ž˜๊ทธ๋กœ GIL์„ ์ œ์–ดํ•˜๋„๋ก ์ถœ์‹œ๋ฉ๋‹ˆ๋‹ค. GIL์€ ๊ธฐ๋ณธ์ ์œผ๋กœ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค. ํ•˜๋‚˜์˜ ABI๋งŒ ์žˆ์Šต๋‹ˆ๋‹ค.

  • ์ถ”๊ฐ€๋กœ 2

    3๊ฐœ์˜ ๋ฆด๋ฆฌ์Šค ํ›„(์ฆ‰, 2028๋…„

    2030๋…„), CPython์€ ๊ธฐ๋ณธ์ ์œผ๋กœ GIL์ด ๋น„ํ™œ์„ฑํ™”๋˜๋„๋ก ์ „ํ™˜๋ฉ๋‹ˆ๋‹ค. GIL์€ ์—ฌ์ „ํžˆ ํ™˜๊ฒฝ ๋ณ€์ˆ˜๋‚˜ ๋ช…๋ น ์ค„ ํ”Œ๋ž˜๊ทธ๋ฅผ ํ†ตํ•ด ๋Ÿฐํƒ€์ž„์—์„œ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ด PEP๋Š” ์ฒซ ๋ฒˆ์งธ ๋‹จ๊ณ„๋ฅผ ๋‹ค๋ฃจ๋ฉฐ, ๋‚˜๋จธ์ง€ ๋‹จ๊ณ„๋Š” ์—ด๋ฆฐ ์ด์Šˆ๋กœ ๋‚จ๊ฒจ์ง‘๋‹ˆ๋‹ค. ์ด ์‹œ๋‚˜๋ฆฌ์˜ค์—์„œ๋Š” ํ™•์žฅ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง€์›ํ•˜๋Š” CPU ์•„ํ‚คํ…์ฒ˜ ๋ฐ OS๋ณ„๋กœ ์ถ”๊ฐ€ CPython ๋นŒ๋“œ๋ฅผ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋Š” ๊ธฐ๊ฐ„์ด 2~3๋…„ ์ •๋„ ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค.

ํ†ตํ•ฉ

์ฐธ์กฐ ๊ตฌํ˜„์€ CPython์˜ ์•ฝ 15,000์ค„์˜ ์ฝ”๋“œ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉฐ, ์•ฝ 15,000์ค„์˜ ์ฝ”๋“œ์ธ mimalloc์„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๋Œ€๋ถ€๋ถ„์˜ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ ์„ฑ๋Šฅ์— ๋ฏผ๊ฐํ•˜์ง€ ์•Š์œผ๋ฉฐ --disable-gil ๋ฐ ๊ธฐ๋ณธ ๋นŒ๋“œ์— ํฌํ•จํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ผ๋ถ€ ๋งคํฌ๋กœ(Py_BEGIN_CRITICAL_SECTION๊ณผ ๊ฐ™์€)๋Š” ๊ธฐ๋ณธ ๋นŒ๋“œ์—์„œ no-op์ด ๋  ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์ €์ž๋Š” --disable-gil ๋นŒ๋“œ๋ฅผ ์ง€์›ํ•˜๊ธฐ ์œ„ํ•ด ๋งŽ์€ #ifdef ๋ฌธ์„ ์˜ˆ์ƒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๋‹จ์ผ ์Šค๋ ˆ๋“œ ์„ฑ๋Šฅ ์™„ํ™”

PEP์—์„œ ์ œ์•ˆํ•œ ๋ณ€๊ฒฝ ์‚ฌํ•ญ์€ GIL์ด ์žˆ๋Š” Python ๋นŒ๋“œ์— ๋น„ํ•ด --disable-gil ๋นŒ๋“œ์˜ ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ฆ๊ฐ€์‹œํ‚ฌ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ๋‹ค์‹œ ๋งํ•ด, ๋‹จ์ผ ์Šค๋ ˆ๋“œ ์„ฑ๋Šฅ์ด ๋” ๋Š๋ ค์งˆ ๊ฒƒ์ž…๋‹ˆ๋‹ค. ์‹คํ–‰ ์˜ค๋ฒ„ํ—ค๋“œ๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋Š” ๋ช‡ ๊ฐ€์ง€ ๊ฐ€๋Šฅํ•œ ์ตœ์ ํ™” ๋ฐฉ๋ฒ•์ด ์žˆ์Šต๋‹ˆ๋‹ค. ํŠนํžˆ ๋‹จ์ผ ์Šค๋ ˆ๋“œ๋งŒ ์‚ฌ์šฉํ•˜๋Š” --disable-gil ๋นŒ๋“œ์—๋Š” ์ด๋Ÿฌํ•œ ์ตœ์ ํ™”๊ฐ€ ์œ ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์žฅ๊ธฐ์ ์ธ ๋ชฉํ‘œ๊ฐ€ ํ•˜๋‚˜์˜ ๋นŒ๋“œ ๋ชจ๋“œ๋ฅผ ๊ฐ–๋Š” ๊ฒƒ์ด๋ผ๋ฉด ์ด๋Ÿฌํ•œ ์ตœ์ ํ™”์™€ ๊ทธ๋“ค์˜ ํŠธ๋ ˆ์ด๋“œ์˜คํ”„ ์„ ํƒ์€ ์—ด๋ฆฐ ๋ฌธ์ œ๋กœ ๋‚จ์Šต๋‹ˆ๋‹ค.# PEP 703: Improving Python Concurrency

์„œ๋ก 

PEP 703์€ CPython ์ธํ„ฐํ”„๋ฆฌํ„ฐ์—์„œ ํŒŒ์ด์ฌ์˜ ๋™์‹œ์„ฑ์„ ๊ฐœ์„ ํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ์ œ์•ˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. ์ด PEP๋Š” ํ˜„์žฌ GIL(Global Interpreter Lock)๋กœ ์ธํ•ด CPython์—์„œ ๋ฐœ์ƒํ•˜๋Š” ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ๋‹ค๋ฃจ๊ณ , ์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ œ์•ˆ์„ ์ œ์‹œํ•ฉ๋‹ˆ๋‹ค.

GIL(Global Interpreter Lock)

GIL์€ CPython ์ธํ„ฐํ”„๋ฆฌํ„ฐ์˜ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋กœ, ํŒŒ์ด์ฌ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•˜๋Š” ๋™์•ˆ์—๋Š” ํ•œ ๋ฒˆ์— ํ•˜๋‚˜์˜ ์Šค๋ ˆ๋“œ๋งŒ์ด ํŒŒ์ด์ฌ ๋ฐ”์ดํŠธ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œํ•œํ•˜๋Š” ์ž ๊ธˆ ๋ฉ”์ปค๋‹ˆ์ฆ˜์ž…๋‹ˆ๋‹ค. ์ด๋กœ ์ธํ•ด ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋„ ๋‹จ์ผ ์ฝ”์–ด๋งŒ ์‚ฌ์šฉ๋˜๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ, CPU ๋ฐ”์šด๋“œ ์ž‘์—…์—์„œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

์ œ์•ˆ๋œ ๊ฐœ์„  ๋ฐฉ๋ฒ•

  1. GIL ์ œ๊ฑฐ: GIL์„ ์™„์ „ํžˆ ์ œ๊ฑฐํ•˜์—ฌ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ์˜ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ์œ„ํ•ด Gilectomy์™€ PyParallel ๋“ฑ์˜ ํ”„๋กœ์ ํŠธ๊ฐ€ ์ œ์•ˆ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.
  2. GIL ๋กœ์ง ๊ฐœ์„ : GIL์„ ์œ ์ง€ํ•˜๋ฉด์„œ GIL ๋กœ์ง์„ ๊ฐœ์„ ํ•˜์—ฌ GIL์ด ๋„ˆ๋ฌด ์ž์ฃผ ์–ป๊ณ  ๋ฐ˜๋‚ฉ๋˜์ง€ ์•Š๋„๋ก ์ œ์–ดํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด GIL ๊ฒฝํ•ฉ ๋ฌธ์ œ๋ฅผ ์™„ํ™”ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  3. ๋‹ค์ค‘ ์ธํ„ฐํ”„๋ฆฌํ„ฐ: ๋‹ค์ค‘ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๋ฅผ ์ง€์›ํ•˜์—ฌ, ๊ฐ๊ฐ์˜ ์ธํ„ฐํ”„๋ฆฌํ„ฐ๊ฐ€ ๋…๋ฆฝ์ ์œผ๋กœ GIL์„ ๊ฐ€์งˆ ์ˆ˜ ์žˆ๋„๋ก ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ™˜๊ฒฝ์—์„œ์˜ ๋™์‹œ์„ฑ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
  4. STM(์†Œํ”„ํŠธ์›จ์–ด ํŠธ๋žœ์žญ์…˜ ๋ฉ”๋ชจ๋ฆฌ): STM์„ ๋„์ž…ํ•˜์—ฌ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ์˜ ๋ฐ์ดํ„ฐ ์ผ๊ด€์„ฑ์„ ๋ณด์žฅํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด GIL ์—†์ด๋„ ์•ˆ์ „ํ•œ ๋™์‹œ์„ฑ์„ ๋‹ฌ์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

๊ฒฐ๋ก 

PEP 703์€ CPython์—์„œ์˜ ๋™์‹œ์„ฑ ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•œ ๋ช‡ ๊ฐ€์ง€ ์ œ์•ˆ์„ ์ œ์‹œํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค. ์ด๋Ÿฌํ•œ ๊ฐœ์„ ์„ ํ†ตํ•ด ํŒŒ์ด์ฌ์˜ ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋”ฉ ํ™˜๊ฒฝ์—์„œ์˜ ์„ฑ๋Šฅ๊ณผ ๋™์‹œ์„ฑ์„ ๊ฐœ์„ ํ•  ์ˆ˜ ์žˆ์„ ๊ฒƒ์œผ๋กœ ๊ธฐ๋Œ€๋ฉ๋‹ˆ๋‹ค.

์ฐธ๊ณ  ๋ฌธํ—Œ

๋ฐ˜์‘ํ˜•
๋‹คํ–ˆ๋‹ค