๋๋์ด Python 3.13.0 ์์ GIL์ด ํด์ ๋์๋ค.

Python 3.13.0 ์ผ๋ก ๋ฉํฐ์ฐ๋ ๋ฉ ์ฑ๋ฅ ํ ์คํธ๋ฅผ ํด๋ณด๋ ค ํ์ง๋ง, ์คํจํ๋ค.

์ฐพ์๋ณด๋, ์ผ๋ฐ CPython 3.13 ์์ ์์ง ์๋๊ณ , GIL์ ํด์ ํ์ฌ ๋น๋ ๋ CPython์ ์ฌ์ฉํด์ผ ํ๋ค.
pyenv ๋ฅผ ํ์ฉํ์ฌ GIL์ด ํด์ ๋ CPython์ ๊ตฌํด๋ณด์
pyenv install 3.13t-dev
pyenv shell 3.13t-dev
python3 --version
# Python 3.13.0+ ํ์์ผ๋ก ๋์ค๋ฉด ์ฑ๊ณต

GIL์ด ํด์ ๋์ด ์ฑ๋ฅ์ด ์ฑ๊ธ ์ฐ๋ ๋ < ๋ฉํฐ ํ๋ก์ธ์ฑ < ๋ฉํฐ ์ฐ๋ ๋ ์์ผ๋ก ๋์๋ค.
๊ทธ๋ ๋ค๋ฉด 8์ฝ์ด 8์ฐ๋ ๋ M3 ๊ธฐ์ค CPU๋ฅผ ์ ๊ฐ๊ตฌ๋์ง ํ์ธํด๋ณด์

ํ ์คํธ ์ฝ๋
import math
import multiprocessing
import sys
import sysconfig
import threading
import time
PYTHON_GIL = 1
# A CPU-bound task: computing a large number of prime numbers
def is_prime(n: int) -> bool:
if n <= 1:
return False
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
def count_primes(start: int, end: int) -> int:
count = 0
for i in range(start, end):
if is_prime(i):
count += 1
return count
def threaded_count_primes(n: int, num_threads: int) -> int:
threads = []
results = [0] * num_threads
def worker(start: int, end: int, index: int) -> None:
results[index] = count_primes(start, end)
step = n // num_threads
for i in range(num_threads):
start = i * step
end = (i + 1) * step if i != num_threads - 1 else n
thread = threading.Thread(target=worker, args=(start, end, i))
threads.append(thread)
thread.start()
for thread in threads:
thread.join()
return sum(results)
def multiprocess_count_primes(n: int, num_processes: int) -> int:
with multiprocessing.Pool(processes=num_processes) as pool:
step = n // num_processes
tasks = [
(i * step, (i + 1) * step if i != num_processes - 1 else n)
for i in range(num_processes)
]
results = [pool.apply_async(count_primes, args=task) for task in tasks]
return sum([result.get() for result in results])
def main() -> None:
# print(f"The GIL active: {sys._is_gil_enabled()}")
print(f"Version of python: {sys.version}")
active = sysconfig.get_config_vars().get("Py_GIL_DISABLED")
if active is None:
print("GIL cannot be disabled")
if active == 0:
print("GIL is [active]")
if active == 1:
print("GIL is [disabled]")
N = 3*10**6
start_time = time.time()
single_threaded_result = count_primes(0, N)
single_threaded_time = time.time() - start_time
print(
f"Single-threaded: {single_threaded_result} primes in [{single_threaded_time:.2f}] seconds"
)
for i in range(1, 16):
NUM_THREADS = i
NUM_PROCESSES = i
start_time = time.time()
threaded_result = threaded_count_primes(N, NUM_THREADS)
threaded_time = time.time() - start_time
print(f"{i} Threaded: {threaded_result} primes in [{threaded_time:.2f}] seconds")
start_time = time.time()
multiprocess_result = multiprocess_count_primes(N, NUM_PROCESSES)
multiprocess_time = time.time() - start_time
print(
f"{i} Multiprocessed: {multiprocess_result} primes in [{multiprocess_time:.2f}] seconds"
)
print()
if __name__ == "__main__":
main()
์๋ณธ ์ถ์ฒ : https://github.com/ArjanCodes/examples/blob/main/2024/gil/main.py
'๐ Python' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
์ดํํฐ๋ธ ํ์ด์ฌ 1์ฅ - ํ์ด์ฌ๋ต๊ฒ ์๊ฐํ๊ธฐ (0) | 2025.03.06 |
---|---|
[Python] *, ** ์ฌ์ฉ๋ฒ (0) | 2025.02.18 |
[Python] ํ์ด์ฌ ๊ฐ๋ฐ์ ๋ฉด์ ์ง๋ฌธ (0) | 2024.05.26 |
[Python] GIL์ด๋? ํ์ด์ฌ์์์ ๋ฉํฐ์ฐ๋ ๋ (0) | 2024.05.06 |
[Python] Pandas, Numpy ์ฑ๋ฅ ํฅ์ (feat.Pandas vs Numpy) (0) | 2024.05.06 |