- สำรวจการอิมพลีเมนต์ Unix pipe บน Linux และวิธีปรับแต่งโปรแกรมทดสอบที่เขียนและอ่านข้อมูลผ่าน pipe
- โปรแกรมเริ่มต้นมีอัตราการประมวลผลประมาณ 3.5GiB/s และปรับปรุงได้ดีขึ้น 20 เท่าผ่านการเพิ่มประสิทธิภาพหลายแบบ
- การเพิ่มประสิทธิภาพเหล่านี้ทำได้โดยการทำโปรไฟล์โปรแกรมด้วยเครื่องมือ
perf ของ Linux
- เนื้อหาได้รับแรงบันดาลใจจากโปรแกรม FizzBuzz ที่ปรับแต่งแล้วซึ่งสามารถผลักเอาต์พุตเข้าสู่ pipe ได้ที่ความเร็วราว 35GiB/s
- เจาะลึกวิธีทำงานภายในของ pipe สาเหตุที่การเขียนและอ่านจากมันช้า และวิธีที่ system call
vmsplice และ splice ช่วยเพิ่มประสิทธิภาพได้
- พูดถึงวิธีที่ Linux paging และการใช้ huge pages สามารถนำไปสู่โปรแกรมเวอร์ชันที่เร็วขึ้นได้
- การปรับแต่งขั้นสุดท้ายรวมถึงการแทนที่การ polling ด้วย busy loop
- การทดสอบดำเนินการบน CPU Intel Skylake i7-8550U และ Linux 5.17
- เนื้อหาอธิบายอย่างละเอียดว่าหน่วยความจำประกอบด้วย page ซึ่งเป็นก้อนขนาดคงที่อย่างไร และ CPU ใช้ page table เพื่อแปลง virtual address เป็น physical address อย่างไร
- เนื้อหาสรุปด้วยข้อสังเกตว่าการเปลี่ยนไปใช้ huge pages ในโปรแกรมช่วยเพิ่มประสิทธิภาพได้ประมาณ 50%
- เนื้อหาพูดถึงการใช้ huge pages บน CPU และวิธีลด Translation Lookaside Buffer (TLB) miss ซึ่งสามารถช่วยเพิ่มประสิทธิภาพได้
- โค้ดเคอร์เนลสมมติว่า
struct page ชี้ไปยัง page ขนาดมาตรฐานของสถาปัตยกรรมปัจจุบัน สำหรับ huge pages นั้น struct page แบบ "head" จะมีข้อมูลของ physical page จริง ส่วน page แบบ "tail" ที่ต่อเนื่องกันจะมีเพียงพอยน์เตอร์ที่ชี้ไปยัง head page
- เคอร์เนลรุ่นใหม่ (หลัง 5.17) มีชนิดใหม่ชื่อ
struct folio สำหรับระบุ head page อย่างชัดเจน ซึ่งช่วยลดความจำเป็นในการตรวจสอบขณะรันไทม์ว่า struct page เป็น head page หรือ tail page และช่วยเพิ่มประสิทธิภาพ
- เนื้อหาพูดถึงแนวคิดของ busy loop เพื่อหลีกเลี่ยงต้นทุนของการซิงโครไนซ์ โดยขอให้
vmsplice คืนค่ากลับมาเมื่อยังเขียนลง pipe ไม่ได้ แล้วให้หมุน busy loop จนกว่าจะพร้อม วิธีนี้อาจเพิ่มประสิทธิภาพได้ 25% แต่แลกกับการใช้ CPU core เต็มที่จนกว่า vmsplice จะพร้อม
- ผู้เขียนสรุปหัวข้อหลักที่กล่าวถึงในเนื้อหา ได้แก่ การทำงานแบบ zero-copy, ring buffer, paging และ virtual memory, รวมถึง synchronization overhead
- ผู้เขียนยังยอมรับว่ามีตัวเลือกและรายละเอียดอื่น ๆ อีกมากที่ไม่ได้กล่าวถึงในเนื้อหา เพราะไม่เกี่ยวข้องหรือไม่น่าสนใจสำหรับเขา
- เนื้อหาได้รับการตอบรับที่ดีจากผู้อ่าน เพราะพวกเขามองว่ามีประโยชน์และน่าสนใจ
1 ความคิดเห็น
ความคิดเห็นบน Hacker News
vmspliceซึ่งทำงานเป็นกลไกหน่วยความจำที่ใช้ร่วมกันขนาดย่อมระหว่างสองโปรเซสvmspliceต้องอาศัยการจัดการบัฟเฟอร์อย่างระมัดระวังทั้งตอนอ่านและเขียน ซึ่งซับซ้อนแต่ก็อาจมีประสิทธิภาพสูงsplice()และvmsplice()ซึ่งถูกมองว่าใช้งานได้ยากในโปรแกรมส่วนใหญ่และจึงไม่ค่อยถูกนำไปใช้stdoutของโปรแกรมหนึ่งไปยังstdinของอีกโปรแกรมหนึ่ง ทำให้งานเป็นแบบzerocopyหรือในกรณีที่ปรับแต่งได้น้อยกว่าก็เป็นonecopyที่ยังคงรวดเร็วperfและเน้นย้ำความสำคัญของมันต่อปริมาณงานที่ประมวลผลได้cat,sed,awk,cut,grep,uniq,jqเป็นต้น