- มีการผสานการใช้งานใหม่ที่อิงกับ io_uring และ Grand Central Dispatch(GCD) เข้าในโมดูล
std.Io.Eventedของไลบรารีมาตรฐาน Zig - การใช้งานทั้งสองแบบทำงานด้วยแนวทาง สลับสแตกใน user space (fibers, stackful coroutines, green threads)
- ขณะนี้ยังอยู่ใน ขั้นทดลอง และยังต้องมีงานต่อเนื่อง เช่น ปรับปรุงการจัดการข้อผิดพลาด ลบการล็อก วิเคราะห์สาเหตุของประสิทธิภาพที่ลดลง และเพิ่มการทดสอบ
- ในโค้ดแอปพลิเคชันชุดเดียวกัน สามารถ สลับเฉพาะ I/O backend เพื่อเปลี่ยนระหว่าง io_uring หรือ GCD ได้อย่างง่ายดาย
- การใช้งานทั้งสองแบบทำงานได้ในคอมไพเลอร์ Zig เช่นกัน และหากทำให้เสถียรในอนาคต ก็มีศักยภาพที่จะพัฒนาเป็น ฐานสำหรับการรวม async I/O ข้ามแพลตฟอร์ม
การใช้งาน std.Io.Evented บนพื้นฐาน io_uring และ GCD
-
ช่วงท้ายของรอบการออก Zig 0.16.0 มีการอัปเดต
std.Io.Eventedให้สอดคล้องกับการเปลี่ยนแปลง API ล่าสุด- การใช้งานที่เพิ่มเข้ามาใหม่คือ io_uring (Linux) และ Grand Central Dispatch(GCD) (macOS)
- การใช้งานทั้งสองแบบใช้เทคนิค สลับสแตกใน user space (fibers, stackful coroutines, green threads)
-
การใช้งานทั้งสองแบบยังอยู่ใน สถานะทดลอง และยังมีโจทย์ปรับปรุงอีกหลายอย่างก่อนใช้งานได้อย่างเสถียร
- ต้อง ปรับปรุงการจัดการข้อผิดพลาด
- ต้อง ลบการล็อก และ วิเคราะห์สาเหตุของประสิทธิภาพที่ลดลง (เมื่อใช้
IoMode.eventedจะเกิดประสิทธิภาพของคอมไพเลอร์ลดลง) - ยังมี ฟังก์ชันบางส่วนที่ยังไม่ถูก implement และ ต้องขยาย test coverage
- จำเป็นต้องเพิ่ม built-in function สำหรับตรวจสอบขนาดสแตกสูงสุดของแต่ละฟังก์ชัน (เพื่อให้ใช้งานได้จริงเมื่อปิด
overcommit)
ตัวอย่างการสลับการใช้งาน I/O
-
สามารถทำงานได้โดยใช้โค้ดแอปพลิเคชันชุดเดิม แล้ว สลับเฉพาะ I/O backend
- ในโค้ดตัวอย่าง หากใช้
std.Io.Eventedแทนstd.Io.Threadedก็จะรันบนพื้นฐาน io_uring - ฟังก์ชัน
appยังคงเดิม และผลลัพธ์ที่แสดง (Hello, World!) ก็เหมือนเดิม
- ในโค้ดตัวอย่าง หากใช้
-
สามารถดูความแตกต่างของสองวิธีการทำงานได้จากการเปรียบเทียบผล
stracehello_threadedใช้การเรียก I/O แบบ thread ทั่วไปhello_eventedใช้ system call ของ io_uring (io_uring_setup,io_uring_enterเป็นต้น)
การนำไปใช้กับคอมไพเลอร์ Zig และสถานะปัจจุบัน
-
ตัวคอมไพเลอร์ Zig เองก็ทำงานได้ปกติโดยใช้
std.Io.Evented- สามารถรันคอมไพเลอร์ได้ทั้งบน io_uring และ GCD
- อย่างไรก็ตาม ยัง ไม่ทราบสาเหตุของประสิทธิภาพที่ลดลง และต้องวิเคราะห์เพิ่มเติม
-
การเปลี่ยนแปลงนี้ทำให้โค้ด Zig เข้าใกล้โครงสร้างที่ สลับการใช้งาน I/O ได้อย่างง่ายดาย มากขึ้น
- เป็นการวางรากฐานสำหรับการจัดการโมเดล async I/O ของแต่ละแพลตฟอร์มแบบรวมศูนย์
งานต่อไป
- ยังต้อง ปรับปรุงประสิทธิภาพและเพิ่มความเข้มแข็งของการทดสอบ เพื่อให้ใช้งานได้อย่างเสถียร
- หากเพิ่ม ความสามารถในการจัดการขนาดสแตก ก็จะช่วยให้ใช้งานได้จริงแม้ในสภาพแวดล้อมที่ปิด overcommit
- หากพัฒนาเสร็จสมบูรณ์ จะช่วยเสริม ชั้น abstraction ของ async I/O ของ Zig ให้แข็งแกร่งขึ้นอีก
บทสรุป
- อัปเดตครั้งนี้เป็นความก้าวหน้าสำคัญในการ ขยายระบบ I/O มาตรฐาน ของ Zig
- การรวม io_uring และ GCD เข้าด้วยกันเป็นการวางรากฐานเพื่อให้เกิด ความสอดคล้องของการประมวลผลแบบ asynchronous ข้ามแพลตฟอร์ม
- เมื่อการทำให้เสถียรเสร็จสิ้นในอนาคต ก็จะเปิดโอกาสให้ Zig สร้าง โมเดล I/O ที่ทั้งประสิทธิภาพสูงและยืดหยุ่น ได้มากขึ้น
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
ฉันไม่ใช่แฟนของ Zig แต่ชอบที่ ทีมเล็ก ๆ พัฒนาอย่างต่อเนื่อง
ท่าทีที่ให้ความสำคัญกับการทดลองและการปรับปรุงทีละน้อยมากกว่าการทำให้เสร็จสมบูรณ์นั้นน่าประทับใจ
ฉันคิดว่าการมุ่งหน้าไปสู่เป้าหมายระยะยาวสำคัญกว่าการรีบออกรุ่น 1.0
สำหรับโปรเจกต์ที่ขับเคลื่อนโดยคนไม่กี่คน นี่ถือเป็นความสำเร็จที่น่าทึ่ง และคนที่ทุ่มเทก็ควรได้รับ การยอมรับ อย่างเหมาะสม
นี่เป็น ประสบการณ์ที่สนุกและมีประสิทธิผลที่สุด เท่าที่เคยมีมา
ความเรียบง่ายของ Zig เข้ากับฉันมากกว่าการจัดการหน่วยความจำอันเข้มงวดของ Rust
ชีวิตมันสั้น และฉันก็แค่อยากสร้างซอฟต์แวร์ที่เร็วและจัดระเบียบมาดี
ทุกครั้งที่มีโพสต์เกี่ยวกับ Zig มักจะมีคำวิจารณ์เยอะมาก แต่ฉันไม่เข้าใจว่าทำไมต้องใส่ใจกันขนาดนั้น
กลับกัน จิตวิญญาณความเป็นวิศวกร ที่ Andrew และทีมพยายามทำให้สิ่งที่ตัวเองเชื่อนั้นเป็นจริงยังให้แรงบันดาลใจมากกว่า
ไม่จำเป็นต้องกังวลว่า Zig จะกลายเป็นกระแสหลักไหม ถ้ามันช่วยแก้ปัญหาได้ก็เพียงพอแล้ว
ไม่จำเป็นต้องปฏิบัติต่อภาษาเหมือนเป็นตัวตนของตัวเอง
ภาษาและไลบรารีคือ ‘ทักษะที่ขายได้’ ดังนั้นผู้คนจึงคำนึงถึงมูลค่าทางตลาดของเครื่องมือที่ตัวเองใช้
นอกจากนี้ คนที่มีอำนาจตัดสินใจก็มักมองวิศวกรเป็นทรัพยากรที่สามารถแทนที่กันได้ ซึ่งก็เป็นปัญหาเช่นกัน
มันเกิดซ้ำมาแล้วกับ Lisp, Ruby, Rust และอื่น ๆ โดย สงครามอัตลักษณ์ เป็นปัญหาเรื้อรังของวงการ
แม้จะต้องมีการดูแลระยะยาวทั้งด้านความปลอดภัยและการรองรับสถาปัตยกรรม แต่ผู้พัฒนาก็มักมองข้ามต้นทุนส่วนนั้น
Zig ยังไม่เสถียร จนแพ็กเกจคอมไพล์ได้เฉพาะบางเวอร์ชัน
จึงอดสงสัยไม่ได้ว่าปัญหาที่แก้ได้ด้วยการปรับปรุงภาษาอื่น ทำไมต้องแก้ด้วยการสร้างภาษาใหม่ด้วย
ฉันรู้สึกว่าก่อนที่ Zig จะถึง 1.0 การตามมันไปก็ยังไม่ค่อยมีความหมาย
โครงสร้างตอนนี้มีโอกาสสูงที่จะถูกเขียนใหม่หลายรอบ
ฉันเองก็เคยสนใจอยู่พักหนึ่ง แต่ไม่แน่ใจว่าจะได้เห็น 1.0 ภายในช่วงชีวิตนี้ไหม
ฟังก์ชันพื้นฐานอย่าง file I/O แทบเหมือนเดิม มีแค่ namespace ที่เปลี่ยน
ฉันคิดว่า ‘ภาษาที่มีชีวิต’ ดีกว่า
แม้หลัง 1.x ไปแล้ว ก็น่าจะมีแนวทางจัดการอินเทอร์เฟซแยกตามเวอร์ชันเพื่อให้ stdlib ยังคงเพรียว
ตอนทำเฟรมเวิร์ก I/O เอง ฉันเจอทั้งการทดสอบที่ไม่เพียงพอและ assembly code ที่ผิด
ชี้ให้เห็นหลายครั้งแล้วแต่ก็ยังไม่ถูกแก้ ทำให้ความเชื่อถือลดลง
โดยเฉพาะในสภาพแวดล้อมคลาวด์ การปรับจูนประสิทธิภาพสามารถลดค่าเซิร์ฟเวอร์ได้มากกว่า 90%
Python หรือ Node มีข้อจำกัด สุดท้ายก็ต้องลงไปใช้ C, C++, Rust หรือ Zig สักตัว
ในบรรดานั้น Zig เรียนรู้ง่าย และอ่านกับทดสอบก็สะดวก
มันเป็นภาษาที่ถูกใช้งานในระดับงานจริงแล้ว
การเปลี่ยนแปลงส่วนใหญ่ให้ความรู้สึกว่าเป็น การปรับปรุงภาษา จริง ๆ
น่าสนใจที่ Zig พยายามลงมือทำ io_uring ก่อน ทั้งที่ฝั่ง Rust เองก็ยังรองรับ io_uring ได้ไม่สมบูรณ์
สำหรับ Rust การออกแบบ abstraction ที่ทั้งปลอดภัยและ zero-cost นั้นยาก
ข่าวนี้ยังเป็นเรื่องของ implementation ที่ยังไม่เสร็จ
ตัวอย่างเช่น เวอร์ชัน GCD ยังไม่มี networking
อินเทอร์เฟซก็กำลังใหญ่ขึ้นเรื่อย ๆ จึงใกล้เคียงกับ snapshot ปัจจุบันมากกว่าจะเรียกว่าสมบูรณ์
ยังลิสต์ งานหลัก 6 อย่าง ที่ต้องทำต่อไว้อย่างชัดเจน
มี issue เกี่ยวกับการปรับแต่งหน่วยความจำสแตก
จำเป็นต้องมีความสามารถที่ทำให้แม้จะใช้
[500]u8ในบล็อกที่ต่างกัน ก็ยังกินพื้นที่ใน stack frame แค่ 500 ไบต์เรื่องนี้สำคัญเป็นพิเศษกับ สแตกของ green-thread coroutine
ฉันมองในแง่บวกกับ ความพยายามปรับปรุงอย่างต่อเนื่อง ของ Zig
ตอนนี้ยังไม่มีภาษาไหนจัดการ io_uring ได้ดีจริง ๆ
ถ้า Zig แก้จุดนี้ได้ดี มันจะได้เปรียบมาก
ฉันคิดว่าท่าทีที่ให้ความสำคัญกับการเรียนรู้และการทดลองมากกว่าความนิ่งนั้นมีค่ากว่า
สำหรับ Zig ฉันชอบใช้ libxev เพื่อควบคุม io_uring โดยตรงมากกว่า
ปัจจัยความสำเร็จของ C คือความเสถียรและวัฒนธรรมการพัฒนาที่สม่ำเสมอ
ฉันชอบที่ Zig ให้ความสำคัญกับ freestanding target อย่างจริงจัง
คาดว่าในเวอร์ชัน 0.16 การนำโค้ดกลับมาใช้ซ้ำจะดีขึ้นอีก
ฉันเพิ่งกลับไปดูภายในของ macOS เป็นครั้งแรกในรอบนาน และดีใจที่ยังคงมี GCD อยู่
ฉันคิดว่านี่เป็นแนวทางด้านการทำงานขนานที่ สมดุลดี
ระหว่างที่ภาษาอื่นเอาแต่ถกเถียง Zig กลับลงมือทำจริง และถ้าจำเป็นก็ย้อนกลับ
ฉันเชื่อว่า API ที่ผ่านการพิสูจน์ในงานจริง คือการออกแบบที่ดีที่สุด
จะคงเวอร์ชันเก่าไว้ก็ได้ หรือถ้าไปเวอร์ชันล่าสุดก็จะได้เครื่องมือที่สะอาดกว่าและเร็วกว่า
มันซับซ้อนแบบ C++ แต่ Zig ยังคงรักษาความเรียบง่ายระดับ C เอาไว้
ส่วน Carbon ก็ยังแทบไม่มีรูปธรรม
Jai ยังอยู่ใน closed beta มา 11 ปีแล้ว แต่ Zig ถูกใช้ใน โปรเจกต์จริงหลายตัว แล้ว
การเปลี่ยนแปลงแบบไร้การยั้งคิด ที่เราเห็นจาก Python 2→3, Rust async, Go generics, C++ และอื่น ๆ กลับเป็นโทษมากกว่า