ความคืบหน้าการพัฒนา No-GIL CPython
(lwn.net)- Python steering council แสดงเจตนาจะอนุมัติ PEP 703 เพื่อทำให้ GIL เป็นตัวเลือก ตลอดหลายรีลีส โดยเงื่อนไขสุดท้ายยังอยู่ระหว่างการปรับให้ลงตัว
- บิลด์
--disable-gilของ CPython 3.13 จะถูกเตรียมไว้ในฐานะฟีเจอร์ทดลอง และประเด็นทางเทคนิคที่ใหญ่ที่สุดตอนนี้คือ stable ABI กับความเข้ากันได้ของ wheel สำหรับโมดูลเสริม - เนื่องจาก wheel
abi3เดิมอาจไม่สามารถใช้กับ no-GIL CPython 3.13 ได้ตรง ๆ จึงมีการหารือเรื่องการเพิ่มabi4, การเปลี่ยนแปลง limited C API และการแปลงแมโครอ้างอิงการนับ refcount ให้เป็นการเรียกฟังก์ชัน - มีความกังวลว่า
pipอาจเลือก wheel สำหรับบิลด์ GIL และ no-GIL ผิด และการติดตั้งผิดแบบเงียบ ๆ นั้นอันตรายกว่าการติดตั้งล้มเหลวแบบชัดเจน - มีการเสนอให้ใช้ชื่อบิลด์ no-GIL ว่า free-threading แทน
nogilแต่ยังต้องแก้ปัญหาเรื่องชื่อไฟล์รัน, shebang, การติดตั้งคู่ขนาน และการแพ็กเกจในดิสทริบิวชันไปพร้อมกัน
ตำแหน่งปัจจุบันของ PEP 703 และ no-GIL CPython
- Python steering council แสดงเจตนาจะอนุมัติ PEP 703 เมื่อปลายเดือนกรกฎาคม โดย PEP นี้มีเนื้อหาเกี่ยวกับการทำให้ global interpreter lock (GIL) เป็นตัวเลือกใน CPython
- แม้เงื่อนไขรายละเอียดของการอนุมัติยังไม่ถูกสรุป окончательно แต่การอภิปรายด้านการใช้งานจริงและการเตรียมระบบนิเวศได้เริ่มเดินหน้าแล้ว
- ในระยะยาวมีภาพเส้นทางไปสู่ CPython เวอร์ชันเดียวที่ไม่มี GIL แต่ในระยะสั้นยังเป็นช่วงทดลองพฤติกรรม no-GIL บนอินเทอร์พรีเตอร์ที่บิลด์ด้วยตัวเลือก
--disable-gil - CPython 3.13 มีกำหนดในเดือนตุลาคม 2024 และบิลด์ no-GIL ของเวอร์ชันนี้จะมีสถานะเชิงทดลอง
stable ABI และความเข้ากันได้ของโมดูลเสริม
- Sam Gross พูดถึงวิธีที่ PEP 703 จะทำงานร่วมกับ stable ABI ของ CPython บน Python discussion forum
- stable ABI มีไว้เพื่อให้โมดูลเสริมทำงานข้ามหลายเวอร์ชันของ CPython ได้ด้วย binary wheel เดียว โดยไม่ต้องรีบิลด์ใหม่ทุกครั้งที่มีรีลีส CPython ใหม่
- ส่วนขยายที่บิลด์สำหรับ stable ABI อาจไม่สามารถทำงานได้ตรง ๆ บนบิลด์ no-GIL ของ CPython 3.13
- เพื่อแก้ปัญหานี้ จึงมีข้อเสนอให้เพิ่มและปรับบางส่วนของ limited C API
- ส่วนขยายที่ใช้เฉพาะ limited C API จะสามารถสร้างไบนารีที่ใช้ stable ABI ได้
- ข้อเสนอการเปลี่ยนแปลงรวมถึงแผนเดิมในการเปลี่ยนแมโครบ้างตัวที่เพิ่มหรือลด reference count ของอ็อบเจ็กต์ให้เป็น การเรียกฟังก์ชัน
- เป้าหมายคือทำให้เกิดไบนารีส่วนขยายที่ใช้งานได้ทั้งบนบิลด์ GIL และ no-GIL
abi3, abi4 และปัญหาการเลือก wheel
- Victor Stinner มองว่าหากการทดลอง no-GIL จะประสบความสำเร็จ จำเป็นต้องมีทางออกที่เรียบง่ายสำหรับส่วนขยายที่ทำงานได้กับอินเทอร์พรีเตอร์ทั้งสองแบบ
- เนื่องจากส่วนขยายที่บิลด์สำหรับ stable ABI บน CPython 3.12 หรือต่ำกว่า จะไม่เข้ากันกับบิลด์ no-GIL หลัง 3.13 จึงมีข้อเสนอให้สร้าง ABI เวอร์ชันใหม่ชื่อ abi4
- stable ABI ปัจจุบันคือ
abi3 - หมายเลข ABI ไม่จำเป็นต้องผูกกับหมายเลขเมเจอร์เวอร์ชันของ CPython เสมอไป
- stable ABI ปัจจุบันคือ
- Gross มองว่าส่วนขยายที่ต้องการรองรับ no-GIL น่าจะรับภาระการสร้าง binary wheel สองชุดได้ในระดับหนึ่ง
- เขากังวลมากกว่าว่าโครงการ no-GIL จะถูกผูกติดกับการปรับปรุง C API และ stable ABI มากเกินไป
- Alex Gaynor ซึ่งมีแพ็กเกจ
abi3wheel หลายตัว ก็มองว่าการต้องสร้างสอง wheel เพียงครั้งเดียวไม่ใช่ภาระที่หนักเกินไป- แต่ประเด็นสำคัญคือ
pipทั้งปัจจุบันและในอนาคตจะเลือก wheel ที่ถูกต้องจากสองตัวนี้ได้หรือไม่
- แต่ประเด็นสำคัญคือ
- Brett Cannon มองว่าลอจิกปัจจุบันของ
pipยังแยกสองเวอร์ชันนี้ไม่ได้ ดังนั้นหากไม่มีการเปลี่ยนแปลงอย่างabi4ทั้งpipรุ่นเดิมและรุ่นเก่าจะไม่สามารถทำงานได้ถูกต้อง
ความกังวลเรื่อง pip ทำงานผิดแบบเงียบ ๆ
- Gross มองว่าในบิลด์ทดลอง
--disable-gilของ CPython 3.13 ไม่จำเป็นต้องกังวลเรื่องการรองรับpipรุ่นเก่ามากนัก- เพราะ
pipรุ่นเก่าที่พังบน Python เวอร์ชันใหม่เป็นเรื่องที่เกิดขึ้นบ่อย - เขายกตัวอย่างกรณี
pip==23.1.1หรือต่ำกว่าที่พังบน CPython 3.13 เพราะไม่มีpkgutil.ImpImporter
- เพราะ
- Paul Moore ผู้ดูแล
pipมองว่า การพังแบบชัดเจน กับ การติดตั้งแพ็กเกจผิดแบบเงียบ ๆ เป็นคนละปัญหา- ยังมีผู้ใช้ที่ใช้
pipรุ่นเก่า - ผลกระทบต่อผู้ใช้ต่างกันระหว่างความล้มเหลวที่ชัดเจนกับข้อผิดพลาดแบบเงียบ
- ยังมีผู้ใช้ที่ใช้
- Moore กังวลว่าหากผู้ใช้ที่อยากทดลองบิลด์ no-GIL หรือ free-threaded ต้องมานั่งดีบักปัญหาความเข้ากันได้ของ ABI อาจทำให้หมดแรงจูงใจ
- Gaynor ก็เห็นว่าถ้า
pipทำงานผิดแบบเงียบ ๆ กับแพ็กเกจที่ได้รับผลกระทบ อาจมี issue หลั่งไหลเข้ามาจำนวนมาก
การติดตั้งแบบคู่ขนานและชื่อไฟล์รัน
- Barry Warsaw ถามว่ามีแผนจะติดตั้งบิลด์ GIL และ no-GIL ไว้ร่วมกันในระบบเดียวหรือไม่
- Gross ตอบว่าสถานการณ์นี้คล้ายกับการติดตั้ง Python คนละเวอร์ชัน
- Cannon มองว่าการใส่ไบนารีสองตัวไว้ใน “fat” wheel เดียวก็เป็นไปได้
- เพียงแต่ชื่อไบนารีภายใน wheel ต้องต่างกัน
- การถกเรื่องชื่อไฟล์รันจึงต่อยอดไปเป็นอีกเธรดหนึ่ง
- Paul Moore มองว่าผู้ใช้ควรสามารถทดสอบโหมด no-GIL ได้ง่าย และเลือกใช้ GIL/no-GIL ได้สะดวก
- หากกระบวนการนี้ยากบน Windows, macOS, Linux ฯลฯ ก็อาจส่งผลลบต่อโครงการ no-GIL
- ผู้ใช้ต้องลองได้ง่าย จึงจะเกิดความต้องการบิลด์ no-GIL และเกิดแรงกดดันต่อผู้ดูแลแพ็กเกจให้จัดทำ wheel ที่เข้ากันได้กับ no-GIL
ข้อถกเถียงเรื่องชื่อ nogil กับ free-threading
- Barry Scott มองว่าชื่อไฟล์รันสำคัญ เพราะต้องใช้ระบุว่าจะเรียกอินเทอร์พรีเตอร์ตัวใดในบรรทัด shebang
- เขายกตัวอย่างชื่ออย่าง
python-nogil3,python-nogil3.13
- เขายกตัวอย่างชื่ออย่าง
- Gregory P. Smith แสดงความเห็นส่วนตัวว่าบิลด์ no-GIL ของ CPython 3.13 เป็นฟีเจอร์ทดลอง ดังนั้นดิสทริบิวชันไม่ควรนำไปไว้ใน
$PATHเริ่มต้น- เขายังมองว่าไม่ควรให้ชื่อไฟล์รันที่ยาวค้างอยู่ใน shebang ไปอีกนาน
- จึงเสนอให้เลื่อนการตัดสินใจเรื่องชื่อสำหรับการติดตั้งออกไปหลัง 3.14
- Petr Viktorin นักพัฒนา Fedora ชี้ว่าดิสทริบิวชันมีแนวโน้มสูงที่จะทำแพ็กเกจอินเทอร์พรีเตอร์ no-GIL ให้ผู้ใช้ทดลอง
- Moore มองว่าอยากระบุบิลด์ free-threaded ด้วยรูปแบบอย่าง
#!/usr/bin/env python3.13-nogil- เพื่อหลีกเลี่ยงการฮาร์ดโค้ดพาธที่ยาวและไม่เป็นธรรมชาติ
- ในเธรดเกี่ยวกับตัวติดตั้งบน Windows ที่ Steve Dower เป็นผู้เริ่ม Smith ระบุว่า steering council ต้องการหลีกเลี่ยงชื่อ
nogil- เหตุผลคือคำนี้สื่อสารกับนักพัฒนาที่ไม่ใช่ core developer ได้ไม่ดี คนส่วนใหญ่ไม่จำเป็นต้องรู้ว่า GIL คืออะไร และยังเป็นการตั้งชื่อเชิงปฏิเสธ
- ทางเลือกที่ถูกเสนอคือคำว่า free-threading
- Gross มองว่า
free-threadingเองก็ไม่ใช่คำที่คนภายนอกเข้าใจง่ายหรือเป็นคำที่ใช้กันแพร่หลาย - ในการอภิปรายจริงมีแรงสนับสนุนต่อชื่อที่สั้นมาก และ
nogilก็เป็นตัวเลือกที่เด่นที่สุดในแง่นั้น - การเปลี่ยนแปลงที่สะท้อนออกมาอย่างเป็นรูปธรรมคือการเปลี่ยน ABI tag ของบิลด์ no-GIL จาก
nเป็นttหมายถึง threading
ข้อเสนอ abi4 และงานที่ยังเหลือ
- Gross และ Viktorin พูดคุยถึงจุดที่เป็นปัญหาในข้อเสนอการเปลี่ยน API และฟีดแบ็กนั้นได้นำไปสู่ข้อเสนอ ABI ใหม่ชื่อ abi4
- Gross ได้สร้าง prototype ของ ABI ใหม่นี้แล้ว
- Viktorin เห็นด้วยกับแนวทางโดยรวม แต่คิดว่ายังต้องเกลารายละเอียดเพิ่มเติม
- Stinner มองว่าควรมี PEP สำหรับ abi4 และ Viktorin ก็รับเรื่องนี้ในฐานะการอภิปรายแบบ pre-PEP
- มีความสับสนเกี่ยวกับการรับประกันความเข้ากันได้ที่เกิดจากการจับคู่ระหว่างเวอร์ชัน limited C API กับ
abi3และประเด็นนี้ก็ส่งผลต่อทิศทางของabi4ด้วย - การตรวจสอบที่เกี่ยวข้องยังดำเนินต่อไป และอาจมีการพูดคุยกันต่อแบบเจอหน้ากันใน core developer sprint ช่วงกลางเดือนตุลาคม
ถ้อยคำอนุมัติขั้นสุดท้ายและผลกระทบระยะยาว
- งานพัฒนา no-GIL หรือ free-threaded CPython ยังเดินหน้าต่อ แต่การอนุมัติขั้นสุดท้ายของ PEP 703 ยังอยู่ระหว่างรอ
- แม้ความล่าช้าจะยืดออกไปพอสมควร แต่ PEP 703 และผลกระทบต่อเนื่องของมันมีแนวโน้มจะส่งอิทธิพลอย่างมากต่อการพัฒนา CPython และระบบนิเวศในอีกกว่า 5 ปีข้างหน้า
- steering council ต้องการทำให้เกณฑ์การอนุมัติชัดเจน
- Thomas Wouters ระบุว่ากำลังเกลาถ้อยคำการอนุมัติที่แม่นยำ และต้องการทำให้การตัดสินใจหลายอย่างชัดเจนขึ้น
- งานบางส่วนอาจดำเนินต่อในช่วง core developer sprint ด้วย
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เมื่อมองดูคอมพิวเตอร์สมัยใหม่ ก็ทำให้นึกได้ว่า parallelism แบบชัดเจน อาจเป็นองค์ประกอบพื้นฐานของวิทยาการคอมพิวเตอร์มากกว่าที่นิยมพูดกันในตำรา
ตอนนี้เราอาจมาถึงจุดที่ต้องเขียนโค้ดแบบขนานอย่างชัดเจนกันอยู่เสมอแล้วก็ได้
ตัวอย่างเช่นลูป
forกำลังถูกแทนที่ด้วยโอเปอเรชันอย่างforeach,map,filterนิพจน์แบบนี้บอกคอมไพเลอร์/อินเทอร์พรีเตอร์ว่าเราต้องการใช้การทำงานบางอย่างกับทุกองค์ประกอบในโครงสร้างข้อมูล แล้วปล่อยให้คอมไพเลอร์/รันไทม์ตัดสินใจว่าจะทำให้ขนานหรือไม่และอย่างไรในการรันเว็บเซอร์วิส แต่ละรีเควสต์มักเร็วพออยู่แล้ว และประโยชน์ที่แท้จริงของ parallelism คือการจัดการหลายรีเควสต์พร้อมกัน ตรงนี้ No-GIL เข้ากันได้ดี
ถ้าภายในรีเควสต์เดียวมีซับรีเควสต์จำนวนมาก ก็มักจัดการด้วยโค้ด async แต่หลายครั้งนั่นไม่ใช่เพราะ async ให้ประสิทธิภาพดีกว่า แต่อาจเพราะการสร้างเธรดมีต้นทุนสูงหรือการจัดการ thread pool ยุ่งยาก async ดีต่อ throughput แต่แย่ต่อ latency และถ้าคุณทำให้รีเควสต์ของเซอร์วิสขนานกัน โดยปกติคุณจะกังวลเรื่อง latency มากกว่า async ชนะมาได้ส่วนใหญ่เพราะใช้งานสะดวก
parallelism อีกแบบหนึ่งเห็นได้ในงานออฟไลน์ขนาดใหญ่ เช่น MapReduce หรือ Presto ซึ่งโดยมากมีลักษณะเหมือนปัญหาแบบแบ่งแล้วพิชิต การฝึกโมเดลบน GPU ก็คล้ายกัน
สิ่งที่ยังไม่เกิดขึ้นคืออัลกอริทึมแบบขนานสูงในเครื่องโลคัล สำหรับเว็บเซอร์วิส ขนาดข้อมูลเล็กเกินกว่าจะได้ประโยชน์ด้าน latency มากนัก การติดตั้งใช้งานซับซ้อน และต้นทุนการประสานงานระหว่างเธรดก็สูง ข้อยกเว้นเล็กน้อยคืออัลกอริทึมแบบ vectorized แต่สิ่งนี้รันบนคอร์เดียวจึงไม่มี overhead ด้านการประสานงาน และ online inference เองก็กลับมาเป็นงานที่ vectorized อย่างมากอีกเช่นกัน
เมื่อเวลาผ่านไป ทั้งสองอย่างก็ดีขึ้นเรื่อย ๆ เหมือนกับที่ภาษาและไลบรารีจำนวนมากปลอดภัยโดยปริยายมากขึ้น ตอนนี้หลายอย่างก็ขนานได้โดยปริยายมากขึ้นเช่นกัน ยังไปไม่สุด แต่ก็ดีใจที่เราไม่ได้เริ่มกันเร็วเกินไป เพราะเทคโนโลยีในช่วง 10 ปีที่ผ่านมา ดีขึ้นมาก
ตัวอย่างเช่น ลองเทียบสิ่งที่ทำได้อย่างปลอดภัยด้วย Rayon ของ Rust กับสิ่งที่เคยทำแบบไม่ปลอดภัยด้วย OpenMP ของ C++
ด้านนอกออกไปอีกก็มีสิ่งที่ฉันทำงานอยู่ด้วย: https://legion.stanford.edu/, https://regent-lang.org/, https://github.com/nv-legate/cunumeric
เพราะมันเป็นรายละเอียดระดับ implementation ถ้าจะทำ abstraction ให้ใช้งานได้ง่ายขึ้นก็ควรทำ
ถ้าเทียบกัน mutex อยู่ที่ราว 25 นาโนวินาที และจะมากขึ้นเมื่อมี contention แต่ mutex เป็นการซิงโครไนซ์ระหว่างจุดต่อจุด
ข้อดีของ Disruptor คือหลายเธรดสามารถรับข้อความเดียวกันได้โดยแทบไม่ต้องออกแรงเพิ่มมากนัก
https://github.com/LMAX-Exchange/disruptor/wiki/Performance-...
https://gist.github.com/rmacy/2879257
ฉันใฝ่ฝันถึงภาษาที่คล้าย Smalltalk แต่ยังคงเป็น single-thread ไปจนกว่าการทำให้ขนานจะมีความหมาย
ฉันกำลังมองหาปัญหา parallelism ที่ไม่ใช่บิ๊กดาต้า parallelism คล้ายกับการเอารถลงถนนเพิ่ม มากกว่าการทำให้รถวิ่งเร็วขึ้น แต่เรายังหากันอยู่ว่ามีงานอะไรบ้างที่ผู้ใช้เดสก์ท็อปหรือมือถือควรทำบนเครื่องโลคัลโดยใช้พลังด้านคณิตศาสตร์ของคอมพิวเตอร์
ในแง่ไอเดียเรื่อง parallelism ฉันก็นึกถึงสถาปัตยกรรม Itanium และ VLIW ด้วย
ใช้
-ngก็ได้ หมายถึง no-gil หรือ next-generationมีทั้งแฟลกคอมไพเลอร์ใหม่ แฟลกลิงเกอร์ใหม่ การลิงก์ไลบรารีคนละชุด ไปจนถึงการใช้คำสั่งคอมไพล์คนละแบบโดยสิ้นเชิง AIX เป็นแบบนั้นชัดมาก
เรื่อง shebang น่าจะดีกว่าถ้าพึ่งพาธรรมเนียมเดิมของ Python:
from __future__ import nogilจากนั้นก็ค่อย hot-swap อินเทอร์พรีเตอร์ ณ จุดนั้น
from __future__ importไม่ใช่คำสั่งรันไทม์ แต่เป็น คำสั่งพิเศษ ที่ใช้แทนแฟลกhttps://docs.python.org/3/reference/simple_stmts.html#future...
future statement ทำงานเป็นรายโมดูล และ GIL/no-GIL ก็ไม่ได้เข้ากับโมเดลนั้นได้ง่ายนัก
ทุกครั้งที่เห็นข้อเสนอนี้ก็อดสงสัยไม่ได้ว่าจะรับประกันอย่างไรให้โปรแกรมยังทำงานได้ถูกต้อง โค้ด Python แบบหลายเธรดที่มีอยู่เดิมจำนวนไม่น้อยเขียนมาอย่างไม่ปลอดภัย
โดยเฉพาะปัญหา data race ที่เห็นซ้ำแล้วซ้ำเล่าทั้งในโค้ดเบสของหลายบริษัทและโปรเจ็กต์โอเพนซอร์ส โปรแกรมพวกนี้ยังไม่พังก็เพียงเพราะพึ่งพาโดยปริยายว่า GIL อนุญาตให้มีเพียงหนึ่งเธรดรันได้ในเวลาเดียวกัน
ถ้า GIL หายไป โปรแกรมเหล่านี้ก็จะพัง Python เป็นภาษาแบบ dynamic type จึงน่าสงสัยมากว่าจะมี static analyzer ที่สามารถค้นหาปัญหาแบบนี้ในโปรแกรม Python เดิมได้หรือไม่
สิ่งที่มีโอกาสเกิดขึ้นมากกว่าคือบั๊กที่แสดงตัวแบบไม่กำหนดแน่นอนในตอนรันไทม์และตรวจจับได้ยาก จะให้โปรแกรม crash ไปเลยยังดีกว่า แต่บั๊กประเภทนี้มีแนวโน้มจะนำไปสู่ผลลัพธ์ที่ทำงานผิดพลาดมากกว่า
หรือบางทีข้อเสนอแบบไม่มี GIL นี้อาจไม่ได้ตั้งใจให้ใช้กับโปรแกรมส่วนใหญ่ก็ได้ มันอาจเป็นเครื่องมือเฉพาะทางมาก ๆ สำหรับบางกรณีเท่านั้น ที่โปรแกรมเมอร์รู้ว่าไม่มี GIL และเขียนโค้ดให้สอดคล้องกับมันได้
GIL หมายความแค่ว่าในช่วงเวลาใดเวลาหนึ่งจะมีได้เพียงหนึ่งเธรดที่รัน Python bytecode เท่านั้น อินเทอร์พรีเตอร์ที่มี GIL ก็ยังสลับเธรดระหว่าง bytecode ได้ และหลายโอเปอเรชันของ Python ต้องใช้หลาย bytecode รวมถึงเมธอดของ built-in type ที่หลายคนคิดว่าเป็น “atomic”
เพราะแบบนั้น Python จึงมีสิ่งอย่าง lock, mutex, semaphore อยู่แล้วแม้ในปัจจุบันจะยังมี GIL ก็ตาม
เธรดที่แย่ง GIL กันสามารถชิง GIL กันในจังหวะที่แย่ได้อยู่แล้วและทำให้เกิดความวุ่นวายได้
ถ้าโปรแกรมจะรันโดยไม่มี GIL ได้ก็ต่อเมื่อ dependency ทั้งหมดอนุญาต แบบนั้นก็น่าจะมีเวลามากพอให้แก้บั๊กเหล่านี้
ถ้าอย่างนั้นกว่าปัญหานี้จะต้องรับมือกันในวงกว้างก็น่าจะใกล้ปี 2030 แล้ว ปกติก็แทบไม่เห็นโปรดักชันที่อัปเกรดรันไทม์ที่ใช้อยู่ไปเป็นรีลีสล่าสุดทันที
ไม่ได้อยากพูดให้แรงเกินไป แต่ Steering Council ก็เคยบอกว่าไม่ต้องการให้เกิดการย้ายเวอร์ชันแบบ 2 ไป 3 อีกรอบ ดังนั้นคนคงไม่อัปเดตกันแบบสบายใจนัก และเนื้อหาส่วนใหญ่ที่มีอยู่บนอินเทอร์เน็ตตอนนี้ก็อาจเสี่ยงต่อการคัดลอกไปใช้ตรง ๆ
ในโค้ด Python จริง ๆ มีบั๊กเกี่ยวกับเธรดอยู่เยอะมาก
OCaml ก็ไม่ได้ผ่านวิวัฒนาการคล้าย ๆ กันหรอกหรือ? สงสัยว่ามีจุดไหนที่พอจะเปรียบเทียบกันได้ระหว่างสองโปรเจ็กต์นี้บ้าง
ดังนั้น API ของเธรดเดิมจึงสร้างเธรดภายใน domain ปัจจุบันได้ และสามารถแยกโค้ดที่คาดว่าจะมีการถือ lock ออกมาได้ โค้ดใหม่สามารถสร้าง domain ใหม่ที่เริ่มต้นด้วยเธรดเดียวแทนได้ และยังตั้งใจใช้สองอย่างนี้ร่วมกันในลักษณะของ scheduling ได้ด้วย
ส่วน Python กำลังพยายามทำให้ lock กลายเป็นตัวเลือกแบบ global อย่างสมบูรณ์นอกเหนือการควบคุมของผู้เขียนไลบรารี แต่ดูเหมือนว่า lock ของ Python ถูกการันตีว่าใช้ปกป้องตัวรันไทม์เองเท่านั้น ดังนั้นโค้ดส่วนใหญ่ที่พึ่ง lock นี้ก็น่าจะมีบั๊กอยู่แล้ว และเพราะเหตุนี้แผนของ Python เองก็ดูพอเป็นไปได้
ถ้าจะมีจุดร่วม ก็คงเป็นการต้องไล่หาและแก้ shared state ที่ไม่คาดคิดทั่วทั้งโค้ดเบสของรันไทม์ และต้องปรับปรุง C ABI
ตอนนี้ Python ก็มีโอกาสไล่ตาม Tcl ในด้านประสิทธิภาพแบบหลายเธรดแล้ว: https://www.hammerdb.com/blog/uncategorized/why-tcl-is-700-f...
ผมกลับอยากพอร์ตโค้ด Python ไป Mojo มากกว่า เพื่อให้ได้ multithreading, SIMD และการเพิ่มความเร็วแบบอื่น ๆ
ไม่อยากย้ายโค้ด Python ไปเป็น nogil Python เหรอ? ถ้างั้นก็โดนดาวน์โหวต
ถ้าจะตั้งชื่อ ก็คงเป็น
python4,python3-gilfoil,python3-gilfreeอะไรทำนองนั้นได้ตอนนี้รู้สึกว่ากระแสที่มุ่งไปที่ Python แบบไม่มี GIL ค่อนข้างแปลก ทีม Faster CPython ตั้งเป้าทะเยอทะยานไว้ว่าจะเพิ่มประสิทธิภาพของ CPython ขึ้น 50% ในทุกรีลีส
ใน 3.11 มีการปรับปรุงจริง แต่ก็ยังห่างไกลจาก 50% มาก และในการทดสอบหลายชุดของเรา 3.12 ก็พอๆ กันหรือช้ากว่าด้วยซ้ำ การทำงานหลายเธรดอย่างแท้จริงคงยอดเยี่ยม แต่ก่อนอื่นผมอยากให้ ประสิทธิภาพแบบเธรดเดียว ดีขึ้นมากกว่า
แน่นอนว่าก็ยอมรับได้ว่าความต้องการของเราอาจไม่ได้เป็นตัวแทนของทุกคน และขอบคุณสำหรับงานทั้งหมดที่ทำให้ Python เป็นภาษาที่ยอดเยี่ยม ถึงอย่างนั้นก็ยังสงสัยว่าผมกำลังมองข้ามอะไรไป
ตอนนี้การใช้หลายคอร์ทำผ่าน multiprocessing ซึ่งมีข้อจำกัดเยอะ เข้าใจนะว่าอาจมีหลาย interpreter เข้ามาพร้อมสิ่งอย่าง coroutine ได้ แต่ถึงอย่างนั้นผมก็ยังชอบตัวเลือกแบบหลายเธรดจริงๆ มากกว่า
ใน nogil Python ยกตัวอย่างเช่น หลายเธรดสามารถเรียกโค้ด C พร้อมมี shared state ที่เข้าถึงได้ผ่านอ็อบเจ็กต์ Python นี่เป็นเรื่องค่อนข้างสำคัญสำหรับ แมชชีนเลิร์นนิง และจริงๆ แล้วรูปแบบปัจจุบันของ PEP นี้ก็มาจากทีม PyTorch
ประสิทธิภาพแบบเธรดเดียวก็สำคัญ แต่สำหรับช่วงที่สำคัญอยู่แล้วก็มีทางอ้อมที่ค่อนข้างดีอย่าง numba, Cython และ Mojo
ลำดับเวลาก็สำคัญ หากนำ nogil เข้ามา งานส่วนใหญ่ของ faster CPython อาจต้องถูกทิ้งไปทั้งหมด จึงต้องมีการประสานงานกันระหว่างทีม
ในโลกอุดมคติ เราควรมีทั้งโหมด nogil และการปรับปรุงประสิทธิภาพแบบเธรดเดียว Guido เองก็ส่งสัญญาณว่ากำลังพิจารณา JIT ที่ซับซ้อนขึ้นด้วย
Python ทำให้การจัดการนามธรรมระดับล่างในภาษาที่ระดับสูงกว่าเป็นเรื่องสะดวกมาก ดังนั้นในฐานะนักพัฒนา Python มานาน ผมจึงไม่ได้เครียดกับ GIL มากนัก
ถ้าต้องเลือกอย่างใดอย่างหนึ่ง ผมเห็นด้วยว่าสำหรับกรณีใช้งานส่วนใหญ่ โค้ดแบบเธรดเดียวที่เร็วขึ้นน่าจะเหมาะกว่า แต่ก็ไม่มีเหตุผลว่าทำไมเราจะมีทั้งสองอย่างไม่ได้
มองย้อนกลับไปก็ชัดเจน แต่ถ้าฝั่ง Python รู้ว่าการเปลี่ยนจาก 2 ไป 3 จะยาวนานและเจ็บปวดขนาดไหน ก็น่าจะยกเครื่องภายใน interpreter ให้หนักกว่านี้มาก
แม้ผ่านการเปลี่ยนผ่านที่ยาวถึง 12 ปี ประสิทธิภาพแบบเธรดเดียว ก็ยังแย่อยู่ และกว่าจะไปถึงการทำงานหลายเธรดอย่างแท้จริงก็ดูเหมือนยังมีการเปลี่ยนผ่านที่เจ็บปวดรออยู่อีกหลายครั้ง
ผมรู้ว่าควรมีเมตตากับการพัฒนาโอเพนซอร์ส แต่ก็เริ่มสงสัยว่าถึงจุดไหนถึงจะเรียกได้ว่าเป็นภาษาที่บริหารจัดการได้แย่มาก
ส่วนที่แย่ที่สุดของ Python คือส่วนที่เปลี่ยนยากเพราะ Python ได้รับความนิยมมากเกินไปและ ecosystem ใหญ่มาก จึงทำให้การเปลี่ยนแปลงทุกแบบยากขึ้นเพราะต้องรักษาความเข้ากันได้ย้อนหลัง
คนมักปกป้อง Python เร็วเกินไป การมองแบบเป็นกลางและไม่ลำเอียงเป็นเรื่องสำคัญ
โปรเจ็กต์ที่ต้องการทั้งประสิทธิภาพและไวยากรณ์แบบ Python ก็ไปทางนั้นได้ ตอนนี้ Python ดูเหมือนกำลังดิ้นรนระหว่างหลายเป้าหมายและไปไม่ถึงสักอย่าง
Perl 5/6 ถูกยกมาเป็นตัวอย่าง และแม้หลังจากชัดเจนแล้วว่าไม่มีใครย้ายตาม ก็ยังใช้เวลาอีกราว 5 ปีถึงจะมีความพยายามทำให้ย้ายได้ง่ายขึ้น