การเปลี่ยนแปลงสำคัญของ Python 3.13
- CPython v3.13.0 มีกำหนดเปิดตัวในวันที่ 7 ตุลาคม 2024
- เวอร์ชันนี้มีการเปลี่ยนแปลงสำคัญ 2 อย่างที่อาจส่งผลอย่างมากต่อประสิทธิภาพของ Python
- เวอร์ชัน "free-threaded" ที่สามารถปิดการทำงานของ Global Interpreter Lock(GIL) ได้
- การรองรับการคอมไพล์แบบ Just-in-Time(JIT) ในสถานะทดลอง
Global Interpreter Lock (GIL)
GIL คืออะไร?
- Python ถูกออกแบบและพัฒนาให้เป็นภาษาอินเทอร์พรีเตอร์แบบเธรดเดียวโดย Guido Van Rossum ในช่วงปลายทศวรรษ 1980
- Python จะคอมไพล์ซอร์สโค้ดเป็นไบต์โค้ดก่อน แล้วอินเทอร์พรีเตอร์จึงทำการรัน
- เพื่อให้เข้าถึงอ็อบเจ็กต์ได้อย่างปลอดภัยจากทุกเธรด จึงใช้ global lock(GIL)
- เป็นล็อก mutual exclusion ระดับโกลบอลที่ป้องกันไม่ให้หลายเธรดรันไบต์โค้ดพร้อมกัน
- แม้จะจำกัดการใช้หน่วยความจำที่ใช้ร่วมกัน แต่ก็เป็นผลดีต่อประสิทธิภาพแบบเธรดเดียว
ทำไม Python ถึงมี GIL
- ในช่วงต้นทศวรรษ 1990 โปรแกรมส่วนใหญ่ยังเป็นแบบเธรดเดียว และประสิทธิภาพของ single-core ก็เพิ่มขึ้นอย่างรวดเร็ว
- จึงไม่มีความจำเป็นต้องแลกประสิทธิภาพแบบเธรดเดียวเพื่อความปลอดภัยของมัลติเธรด
- สามารถใช้หลายโปรเซสเพื่อใช้ประโยชน์จากหลายคอร์ได้ (
multiprocessing โมดูล)
แล้วทำไมถึงเอา GIL ออกตอนนี้?
- นักพัฒนาหลักของ Python ต้องการเอา GIL ออกมานานแล้ว แต่กังวลว่าประสิทธิภาพแบบเธรดเดียวจะลดลงจึงยังไม่ทำ
- ในช่วงหลัง เมื่อระบบหลายคอร์กลายเป็นเรื่องปกติ ข้อจำกัดด้านมัลติเธรดจาก GIL จึงกลายเป็นปัญหามากขึ้น
- โครงการ "Faster CPython" ที่ได้รับการสนับสนุนจาก Microsoft มีส่วนช่วยปรับปรุงประสิทธิภาพของ Python
- Sam Gross เสนอแนวทาง implementation แบบไม่มี GIL จน PEP 703 ได้รับการรับรอง
- แผนการนำมาใช้แบบค่อยเป็นค่อยไป: ตัวเลือกเชิงทดลอง → รองรับอย่างเป็นทางการ → โหมดค่าเริ่มต้น
- จากพื้นฐานเหล่านี้ แผนการถอด GIL ออกอย่างค่อยเป็นค่อยไปจึงได้รับการอนุมัติ
ประสิทธิภาพเป็นอย่างไร?
- เมื่อเปิดใช้ free-threading ประสิทธิภาพแบบเธรดเดียวจะลดลงประมาณ 20%
- มัลติเธรดที่ปิด GIL จะแสดงให้เห็นถึงการเพิ่มขึ้นของประสิทธิภาพอย่างมาก
- มัลติเธรดที่ยังเปิด GIL จะช้ากว่าการรันแบบเธรดเดียว
- มัลติเธรดที่ปิด GIL ให้ประสิทธิภาพใกล้เคียงกับ multiprocessing
จะใช้ Free-threading Python ได้อย่างไร?
- สามารถใช้เวอร์ชัน free-threading ได้โดยติดตั้ง Python 3.13.0rc2t ด้วย pyenv
- โดยค่าเริ่มต้น GIL จะถูกปิดไว้ และสามารถเปิดกลับระหว่างรันไทม์ได้ด้วย
-X gil=1
- หาก import โมดูลที่ไม่รองรับ GIL free ระบบจะเปิด GIL ให้อัตโนมัติ
JIT (Just-in-Time) Compiler
JIT คืออะไร?
- ต่างจากการคอมไพล์แบบ ahead-of-time ดั้งเดิม JIT คือเทคนิคที่สร้าง machine code ก่อนรันจริงไม่นาน
- ก่อนหน้า Python 3.13 การทำงานจะเป็นการแปลงไบต์โค้ดเป็นภาษาเครื่องทีละคำสั่งระหว่างรัน
- เมื่อมี JIT ก็สามารถแปลงไบต์โค้ดเป็นภาษาเครื่องได้ทีเดียว และอัปเดตได้เมื่อจำเป็น
- เทคนิคที่นำมาใช้ใน Python 3.13 คือ JIT แบบ "copy-and-patch" ซึ่งแพตช์ bytecode ที่ตรงกับเทมเพลตที่กำหนดไว้ล่วงหน้าให้เป็น native code
- JIT compiler ที่ก้าวหน้ากว่านี้สามารถปรับแต่งส่วนของโค้ดที่ถูกเรียกใช้งานบ่อยหรือเป็น "hot" path ได้
JIT ส่งผลอย่างไร?
- ในระยะสั้น วิธีเขียนหรือรันโค้ด Python อาจแทบไม่เปลี่ยนแปลงมากนัก
- อย่างไรก็ตาม คาดว่าจะมีการปรับปรุงประสิทธิภาพอย่างต่อเนื่องจนสามารถแข่งขันกับภาษาอื่นได้
จะใช้ JIT ได้อย่างไร?
- ใน Python 3.13, JIT ยังอยู่ในสถานะทดลองและไม่ได้เปิดใช้งานเป็นค่าเริ่มต้น
- สามารถเปิดใช้ตอน build ได้ด้วยตัวเลือก
PYTHON_CONFIGURE_OPTS="--enable-experimental-jit"
- ระหว่างรันไทม์สามารถควบคุมการเปิดหรือปิดได้ด้วย
PYTHON_JIT=0/1
บทสรุป
- Python 3.13 เป็นรีลีสใหญ่ที่นำแนวคิดและความสามารถใหม่ที่น่าสนใจเข้าสู่ runtime
- การถอด GIL และการเพิ่ม JIT เป็นสัญญาณของการเปลี่ยนแปลงสำคัญ
- แม้ในระยะสั้นอาจยังไม่เห็นความเปลี่ยนแปลงใหญ่ แต่ในระยะยาวจะส่งผลเชิงบวกต่อประสิทธิภาพของ Python
- เมื่อ free-threading และ JIT เติบโตเต็มที่ คาดว่าจะส่งผลอย่างมากต่อประสิทธิภาพ โดยเฉพาะงานแบบ CPU-bound
ความเห็นของ GN⁺
- การอัปเดต Python 3.13 ครั้งนี้ดูจะนำการเปลี่ยนแปลงครั้งใหญ่มาสู่ ecosystem ของ Python โดยการถอด GIL น่าจะช่วยลดคอขวดของมัลติเธรด และการเพิ่ม JIT ก็น่าจะช่วยให้ความเร็วโดยรวมดีขึ้น
- อย่างไรก็ตาม กว่าการเปลี่ยนแปลงเหล่านี้จะเสถียรอย่างสมบูรณ์ก็น่าจะต้องใช้เวลา อาจเกิดปัญหาความเข้ากันได้กับแพ็กเกจเดิมอย่าง C extension และในการเขียนโปรแกรมมัลติเธรดก็อาจมีบั๊กใหม่ เช่น race condition เกิดขึ้นได้
- ความช้าของ Python มักถูกยกเป็นจุดอ่อนมาโดยตลอด และหวังว่าการอัปเดตครั้งนี้จะช่วยเปลี่ยนมุมมองดังกล่าวได้ หากยังคงข้อดีเดิมเรื่อง productivity และ readability ไว้ได้ พร้อมทั้งเพิ่มความเร็ว Python ก็จะกลายเป็นภาษาที่ถูกใช้งานอย่างแพร่หลายยิ่งขึ้น
- ถึงอย่างนั้นก็ยังมีข้อจำกัดพื้นฐานจากการเป็นภาษาที่มี dynamic type อยู่ดี ความพยายามในการดึงข้อดีของภาษาแบบ static type เข้ามาก็ควรเดินหน้าต่อไป โดยมองว่าการใช้ type hinting และ Cython ที่เพิ่งถูกนำมาใช้ใน Python อย่างจริงจังมากขึ้น อาจช่วยบรรเทาปัญหานี้ได้ในระดับหนึ่ง
- โดยสรุป Python 3.13 ดูจะนำมาซึ่งการเปลี่ยนแปลงที่น่าสนใจและเป็นบวก หวังว่านักพัฒนาจะเข้าใจและใช้ประโยชน์จากการเปลี่ยนแปลงครั้งนี้ได้ดี เพื่อสร้างโปรแกรม Python ที่ดียิ่งขึ้น
3 ความคิดเห็น
ทั้งการนำ GIL ออกและ JIT แม้ตอนนี้อาจยังเห็นผลไม่มากนัก แต่ก็เป็นพัฒนาการที่สำคัญอย่างยิ่งซึ่งจะเปลี่ยนทิศทางของ Python คงน่าจับตาอนาคตของ Python ที่จะสลัดภาพลักษณ์ว่าเป็น "ภาษาที่ช้าที่สุด" ทิ้งไป และถูกนำไปใช้ในอีกหลายด้านมากขึ้นต่อจากนี้
ความสำคัญของ Free threading (การนำ GIL ออก) ได้ถูกรวบรวมไว้อย่างดีใน PEP 703 พร้อมทั้งความคิดเห็นจากผู้คนหลากหลายฝ่าย
นอกจากนี้ตาม PEP ดังกล่าว ระบุว่าประสิทธิภาพที่ลดลงในเธรดเดี่ยวมีเพียง 5~6% เท่านั้น ดังนั้นข้ออ้างในบทความนั้นและคอมเมนต์บางส่วนบน hn ที่บอกว่าประสิทธิภาพลดลง 20~50% จึงฟังดูน่าเชื่อถือได้ยาก และก็ไม่มีแหล่งอ้างอิงที่ตรวจสอบได้ด้วย
ความคิดเห็นใน Hacker News
มีความเห็นว่าการลบ GIL จะทำให้โปรแกรม Python ทั่วไปช้าลงและเพิ่มความซับซ้อน
มีการบ่นว่าไม่สามารถดาวน์โหลดเวอร์ชันที่เปิดใช้ JIT ได้
มีความเห็นว่าคล้ายกับคำคล้องจอง "Jack and Jill went up the hill"
มีประสบการณ์ว่าในโปรแกรมขนาดเล็กที่ใช้หน่วยความจำน้อยและรันช่วงสั้น ๆ การปิด garbage collection ช่วยเพิ่มความเร็วได้มาก
มีความเห็นว่านี่เป็นสรุปที่ดีสำหรับคนที่ไม่พอใจกับคำอธิบายในตอนที่มีการพูดถึงการลบ GIL ครั้งแรกในปี 2021
ตั้งคำถามว่าการปรับแต่งให้เหมาะกับกรณีไม่มี GIL นั้นเป็นไปไม่ได้จริงหรือ
มีข่าวว่าวันที่ออกรีลีสถูกเปลี่ยนจาก 2 ตุลาคมเป็น 7 ตุลาคม
มีความเห็นว่ามีการอ้างว่าประสิทธิภาพของ nogil ลดลง 20% แต่จริง ๆ อาจสูงได้ถึง 50%
มีความเห็นว่าพาดหัวน่าตกใจ
มีคำถามว่ากำลังหาลิงก์ไปยังงานล่าสุดเกี่ยวกับการทำ parallelization อัตโนมัติ