4 คะแนน โดย GN⁺ 2024-03-31 | 1 ความคิดเห็น | แชร์ทาง WhatsApp

แนะนำ RCU

  • ระบบปฏิบัติการเป็นหนึ่งในโปรแกรมที่ไวต่อประสิทธิภาพมากที่สุดที่เราใช้งานกันทุกวัน
  • ระบบปฏิบัติการสามารถทำงานให้เร็วขึ้นได้เสมอ และนักพัฒนาเคอร์เนลกับไดรเวอร์ต่างก็ทุ่มเทให้กับการปรับแต่งโค้ด
  • ระบบปฏิบัติการต้องการการทำงานพร้อมกันในระดับสูง โดยทำหน้าที่จัดตารางโปรเซสและเธรดใน user space และยังมีเธรดของตัวเองรวมถึงตัวจัดการ interrupt ที่โต้ตอบกับฮาร์ดแวร์

หลักการทำงานของ RCU

  • เมื่อจำเป็นต้องเปลี่ยนข้อมูลที่ถูกอ่านบ่อยแต่ถูกเขียนไม่บ่อยแบบอะตอมมิก (เช่น อุปกรณ์ USB ที่เชื่อมต่ออยู่ในขณะนั้น) จะใช้กลยุทธ์ RCU (Read, Copy, Update)
  • อ่านข้อมูล คัดลอกออกมาแล้วแก้ไข จากนั้นอัปเดตพอยน์เตอร์ไปยังเวอร์ชันใหม่แบบอะตอมมิก
  • วิธีนี้ใช้งานง่ายและไม่มีการรอคอย แต่ก็อาจทำให้เกิด memory leak ได้

การแก้ปัญหา memory leak

  • เพื่อป้องกัน memory leak แทนที่จะลบข้อมูลเก่าภายในฟังก์ชันอัปเดตทันที สามารถเลื่อนการลบออกไปจนกว่าจะไม่มีผู้อ่านที่กำลังอ่านข้อมูลนั้นอยู่
  • ทำให้สามารถจัดการหน่วยความจำได้อย่างปลอดภัย โดยให้ตัวเขียนรอการลบข้อมูลจนกว่าผู้อ่านจะอ่านเสร็จ

การใช้งาน RCU ในโลกจริง

  • RCU ถูกใช้งานใน Linux หลายหมื่นแห่ง และยังถูกใช้ในไลบรารี C++ ของ Facebook อย่าง Folly และใน crossbeam-epoch ของ Rust ด้วย
  • RCU เป็นกลไก synchronization ที่ขับเคลื่อนด้วยข้อกำหนดด้านประสิทธิภาพและ latency และมอบรูปแบบการจัดการหน่วยความจำที่คล้ายกับ garbage collection

ความเข้าใจผิดเกี่ยวกับ garbage collection

  • ความเชื่อที่ว่า garbage collection ช้ากว่าการจัดการหน่วยความจำด้วยมือ จะพังทลายลงอย่างรวดเร็วเมื่อพิจารณารายละเอียดให้ลึกขึ้น
  • ฟังก์ชัน free() ไม่ได้ฟรีจริง ๆ และตัวจัดสรรหน่วยความจำเองก็ต้องเก็บสถานะภายในไว้จำนวนมาก
  • garbage collector สมัยใหม่มีการเพิ่มประสิทธิภาพแบบ moving และ generational ซึ่งช่วยให้ได้ทั้ง throughput สูงและประสิทธิภาพด้านแคชที่ดี

ภาพลวงตาของการควบคุม

  • บางครั้งนักพัฒนาต้องการสร้างระบบเรียลไทม์ แต่ในความเป็นจริงแล้วก็ไม่ได้มีการควบคุมการจัดการหน่วยความจำได้อย่างสมบูรณ์
  • ระบบปฏิบัติการทำได้เพียงคาดเดาความตั้งใจของนักพัฒนาเกี่ยวกับการจัดสรรหน่วยความจำ และบางครั้งการเข้าถึงพอยน์เตอร์แบบธรรมดาก็อาจกลายเป็น disk I/O ได้

บทสรุป

  • ไม่ใช่ว่าซอฟต์แวร์ทุกชนิดจะได้ประโยชน์จาก garbage collection แต่ garbage collection เป็นเครื่องมือที่มีประโยชน์ และแม้แต่ในหมู่โปรแกรมเมอร์ระบบเองก็ไม่ควรหวาดกลัวมันอีกต่อไป

ความเห็นของ GN⁺

  • RCU เป็นเทคนิคที่มีประสิทธิภาพในการเพิ่มความสามารถในการทำงานพร้อมกัน ขณะเดียวกันก็รักษาความสอดคล้องของข้อมูลไว้ในสภาพแวดล้อมแบบมัลติเธรด ซึ่งเป็นองค์ประกอบสำคัญอย่างมากในงานคอมพิวเตอร์ประสิทธิภาพสูงหรือระบบเรียลไทม์
  • ตัวอย่างของ RCU ที่ช่วยทลายความเชื่อเดิมเกี่ยวกับ garbage collection มอบมุมมองใหม่ด้านการจัดการหน่วยความจำให้กับนักพัฒนา โดยเฉพาะในงาน system programming ที่เรื่องนี้มีความสำคัญอย่างยิ่ง
  • โปรเจ็กต์อื่นที่มีความสามารถคล้าย RCU ได้แก่ ConcurrentLinkedQueue ของ Java และ ConcurrentBag ของ .NET ซึ่งต่างก็มีโครงสร้างข้อมูลแบบ lock-free เช่นกัน
  • เมื่อนำเทคโนโลยี RCU มาใช้ ควรพิจารณาความต้องการของระบบและเป้าหมายด้านประสิทธิภาพ รวมถึงทำความเข้าใจทั้งข้อดีและต้นทุนที่อาจเกิดขึ้นจากการใช้งานเทคนิคนี้
  • บทความนี้อาจช่วยให้นักพัฒนาเข้าใจการจัดการหน่วยความจำและการทำงานพร้อมกันได้ลึกซึ้งยิ่งขึ้น ทบทวนสมมติฐานเดิม ๆ และสำรวจแนวทางแก้ปัญหาใหม่ ๆ

1 ความคิดเห็น

 
GN⁺ 2024-03-31
ความคิดเห็นบน Hacker News
  • มีข้อเสนอแนะให้ลองดูเทคนิค garbage collection (GC) แบบขนานที่ล้ำหน้าสำหรับ MPL และ MaPLe

    • ได้รับรางวัลบทความดีเด่นจาก POPL 2024 และรางวัล ACM SIGPLAN Distinguished Paper Award ประจำปี 2023
    • ข้อเสนอหลักมีดังนี้:
      • disentanglement ที่อิงกับ garbage collection แบบขนานซึ่งมีประสิทธิภาพที่พิสูจน์ได้
      • การควบคุมความละเอียดอัตโนมัติที่มีประสิทธิภาพที่พิสูจน์ได้
  • การใช้ RCU เป็นกลไกซิงโครไนซ์สำหรับ garbage collection เป็นเรื่องที่น่าสนใจ

    • การย้ายความรับผิดชอบในการคืนหน่วยความจำจากผู้เขียนไปยังผู้อ่านคนสุดท้ายมีความสมเหตุสมผล
    • เพื่อปรับปรุงประสิทธิภาพ อาจควรพิจารณาย้ายการคืนหน่วยความจำไปยังโปรเซสแบบแบตช์เฉพาะ แทนที่จะให้ผู้อ่านเป็นผู้ทำ
  • ความเข้าใจผิดทั่วไปเกี่ยวกับการจัดการหน่วยความจำ

    • เชื่อว่าโปรแกรมเมอร์รู้เวลา pause ที่เหมาะสมที่สุดสำหรับการจัดการหน่วยความจำ
    • ในเกมและโปรแกรมเทรดคริปโต โปรแกรมเมอร์อาจรู้เวลา pause ที่เหมาะสมที่สุดจริง
  • กรณีใช้งานของ RCU ฟังดูน่าเชื่อถือ แต่ประสบการณ์กับ garbage collection ในสถานการณ์อื่นกลับไม่ค่อยดี

    • อ่านแล้วเหมือนเป็นการอ้างว่าโซลูชันจัดการหน่วยความจำแบบปรับแต่งเองอาจให้ประสิทธิภาพดีที่สุด
    • มีการพูดถึงความเข้าใจผิดที่ว่า free() จะคืนหน่วยความจำให้ OS
  • เมื่อใช้ garbage collection การจัดสรรใหม่จะเกิดจาก RAM ไม่ใช่แคช

    • อาจส่งผลต่อประสิทธิภาพอย่างมาก
    • มีตัวอย่าง benchmark ในภาษา Julia
  • garbage collection แบบ tracing ที่ดีนั้นเอาชนะการจัดการหน่วยความจำด้วยมือตั้งนานแล้วในแง่ throughput

    • ช่วงหลังมานี้ latency ก็อยู่ในระดับที่ยอมรับได้สำหรับแอปพลิเคชันส่วนใหญ่
    • การใช้หน่วยความจำเป็นประเด็นหลักที่ต้องพิจารณา
  • สิ่งหนึ่งที่เข้ากันได้ดีกับ garbage collection คือ async/await

    • ใน Rust การใช้ async/await ก่อปัญหาเมื่อผูกเข้ากับการจัดการหน่วยความจำ
  • หลังจากปูพื้นเรื่อง RCU แล้วเปลี่ยนไปพูดถึง garbage collection ทั่วไปนั้นค่อนข้างน่าแปลกใจ

  • เวลาพัฒนาซอฟต์แวร์จะพิจารณาอยู่สองกรณี

    • สำหรับ hot path จะใช้ตัวจัดสรรแบบปรับแต่งเอง ส่วนกรณีอื่น garbage collection สะดวกกว่า
  • การเปลี่ยนจาก RCU ไปเป็น garbage collection แบบ tracing ทั่วไปดูเหมือนเป็นกลยุทธ์ที่แนบเนียน

    • การจัดการหน่วยความจำด้วยมือมีมากกว่าแค่การเรียก malloc/free
  • สำหรับโปรแกรมเมอร์สายระบบ การระบุว่าอะไรจะถูก garbage collection ได้เมื่อไรเป็นเรื่องยาก

  • เครื่องมือจัดการอายุการใช้งานใน Rust และ C++ ช่วยให้การคืนหน่วยความจำเป็นอัตโนมัติได้ แต่ไม่ได้ทำให้ความซับซ้อนเรียบง่ายลง