14 คะแนน โดย GN⁺ 2024-09-29 | 3 ความคิดเห็น | แชร์ทาง WhatsApp

การเปลี่ยนแปลงสำคัญของ 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 ความคิดเห็น

 
ilotoki0804 2024-09-30

ทั้งการนำ GIL ออกและ JIT แม้ตอนนี้อาจยังเห็นผลไม่มากนัก แต่ก็เป็นพัฒนาการที่สำคัญอย่างยิ่งซึ่งจะเปลี่ยนทิศทางของ Python คงน่าจับตาอนาคตของ Python ที่จะสลัดภาพลักษณ์ว่าเป็น "ภาษาที่ช้าที่สุด" ทิ้งไป และถูกนำไปใช้ในอีกหลายด้านมากขึ้นต่อจากนี้

 
ilotoki0804 2024-09-30

ความสำคัญของ Free threading (การนำ GIL ออก) ได้ถูกรวบรวมไว้อย่างดีใน PEP 703 พร้อมทั้งความคิดเห็นจากผู้คนหลากหลายฝ่าย
นอกจากนี้ตาม PEP ดังกล่าว ระบุว่าประสิทธิภาพที่ลดลงในเธรดเดี่ยวมีเพียง 5~6% เท่านั้น ดังนั้นข้ออ้างในบทความนั้นและคอมเมนต์บางส่วนบน hn ที่บอกว่าประสิทธิภาพลดลง 20~50% จึงฟังดูน่าเชื่อถือได้ยาก และก็ไม่มีแหล่งอ้างอิงที่ตรวจสอบได้ด้วย

 
GN⁺ 2024-09-29
ความคิดเห็นใน Hacker News
  • มีความเห็นว่าการลบ GIL จะทำให้โปรแกรม Python ทั่วไปช้าลงและเพิ่มความซับซ้อน

    • ตั้งคำถามถึงประโยชน์ที่ได้จริง
    • หากจำเป็นต้องใช้หลายคอร์ของ CPU ให้คุ้มค่าที่สุด ก็ใช้วิธีให้ OS รันหลายอินสแตนซ์ของโปรแกรม แล้วเพิ่มตรรกะการทำงานแบบขนานเข้าไปในโปรแกรม
  • มีการบ่นว่าไม่สามารถดาวน์โหลดเวอร์ชันที่เปิดใช้ JIT ได้

    • แม้จะคอมไพล์ Python 3.13 ด้วยตัวเองได้ แต่ก็มีการแชร์ประสบการณ์ว่าหลายคนไม่ลองทำและไม่ส่งฟีดแบ็ก
  • มีความเห็นว่าคล้ายกับคำคล้องจอง "Jack and Jill went up the hill"

    • สับสนว่า "up the hill" หมายถึงอะไร
    • เปิดตัว JIT แล้ว แต่ก็ยังสงสัยว่าได้ลบ GIL ออกหรือไม่
  • มีประสบการณ์ว่าในโปรแกรมขนาดเล็กที่ใช้หน่วยความจำน้อยและรันช่วงสั้น ๆ การปิด garbage collection ช่วยเพิ่มความเร็วได้มาก

    • สงสัยว่าสามารถทำให้เป็นอัตโนมัติได้หรือไม่
    • กล่าวถึงความเสี่ยงของ edge case ที่โปรแกรมเล็ก ๆ ใช้หน่วยความจำทั้งหมด
  • มีความเห็นว่านี่เป็นสรุปที่ดีสำหรับคนที่ไม่พอใจกับคำอธิบายในตอนที่มีการพูดถึงการลบ GIL ครั้งแรกในปี 2021

  • ตั้งคำถามว่าการปรับแต่งให้เหมาะกับกรณีไม่มี GIL นั้นเป็นไปไม่ได้จริงหรือ

    • มีความเห็นว่าการช้าลง 20% เป็นปัญหาใหญ่
  • มีข่าวว่าวันที่ออกรีลีสถูกเปลี่ยนจาก 2 ตุลาคมเป็น 7 ตุลาคม

    • มีการให้ลิงก์ที่เกี่ยวข้อง
  • มีความเห็นว่ามีการอ้างว่าประสิทธิภาพของ nogil ลดลง 20% แต่จริง ๆ อาจสูงได้ถึง 50%

    • JIT ไม่ได้ช่วยมากนัก
    • มองว่าเป็นรีลีสที่น่าผิดหวังซึ่งสะท้อนปัญหาทางสังคมและองค์กรของ CPython
    • อ้างว่ามีบางคนคอยสัญญาฟีเจอร์ ปิดปากคนที่ไม่ได้กระตือรือร้นเต็มที่ 100% และสุดท้ายก็ได้ผลลัพธ์ที่ไม่เป็นไปตามความคาดหวัง
  • มีความเห็นว่าพาดหัวน่าตกใจ

  • มีคำถามว่ากำลังหาลิงก์ไปยังงานล่าสุดเกี่ยวกับการทำ parallelization อัตโนมัติ

    • มีการให้ลิงก์เกี่ยวกับแนวทางที่เขียนโค้ดแบบ single-thread แล้วให้คอมไพเลอร์สร้างโค้ดแบบ multithread