ปัญหาการสิ้นเปลืองหน่วยความจำของ Lua ได้รับการแก้ไขแล้ว เมื่อการปรับปรุงอาเรย์แบบใหม่จะเข้าสู่รุ่นถัดไป

ทีมชุมชน BigGo
ปัญหาการสิ้นเปลืองหน่วยความจำของ Lua ได้รับการแก้ไขแล้ว เมื่อการปรับปรุงอาเรย์แบบใหม่จะเข้าสู่รุ่นถัดไป

Lua ภาษาโปรแกรมมิ่งที่มีน้ำหนักเบาและได้รับความนิยมในระบบฝังตัวและการพัฒนาเกม ได้สิ้นเปลืองหน่วยความจำเกือบครึ่งหนึ่งอย่างเงียบๆ เมื่อจัดเก็บอาเรย์ งานวิจัยเชิงวิชาการล่าสุดได้เปิดเผยความไม่มีประสิทธิภาพนี้และเสนอแนวทางแก้ไขที่อาจจะเข้าสู่รุ่นอย่างเป็นทางการถัดไปของภาษานี้ในเร็วๆ นี้

ปัญหานี้เกิดจากวิธีที่ Lua แสดงค่าต่างๆ ภายใน แต่ละค่าจะมีทั้งข้อมูลและแท็กประเภท แต่เนื่องจากข้อกำหนดการจัดตำแหน่งหน่วยความจำ วิธีการนี้จึงสิ้นเปลืองพื้นที่ประมาณ 40% ผ่านการเติมช่องว่าง สำหรับโปรแกรมขนาดเล็ก อาจจะไม่สำคัญมาก แต่สำหรับแอปพลิเคชันที่มีอาเรย์ขนาดใหญ่ อาจหมายถึงการใช้หน่วยความจำมากกว่าที่จำเป็น 40%

ปัญหาการสูญเสียหน่วยความจำใน Array ของ Lua ในปัจจุบัน:

  • การสูญเสียจาก Padding: ~40% ของหน่วยความจำสูญหายไปเนื่องจากช่องว่างการจัดเรียง
  • ขนาดโครงสร้าง TValue: 16 ไบต์ (ระบบ 64 บิต)
  • การใช้ข้อมูลจริง: เพียง ~60% ของหน่วยความจำที่จัดสรร
  • ผลกระทบ: รุนแรงเป็นพิเศษสำหรับ array ขนาดใหญ่ที่มีหลายพันองค์ประกอบ

ความท้าทายทางเทคนิคเบื้องหลังการสิ้นเปลือง

Lua ใช้สิ่งที่นักวิจัยเรียกว่า tagged values - ข้อมูลแต่ละชิ้นจะมาพร้อมกับข้อมูลเกี่ยวกับประเภทของมัน การเลือกออกแบบนี้ทำให้ภาษามีความยืดหยุ่นและเป็นแบบไดนามิก ทำให้ตัวแปรสามารถเปลี่ยนประเภทได้ระหว่างการทำงาน อย่างไรก็ตาม การใช้งานปัจจุบันจัดเก็บ tagged values เหล่านี้ในลักษณะที่สร้างช่องว่างในหน่วยความจำเนื่องจากข้อจำกัดการจัดตำแหน่ง

ลองนึกภาพเหมือนการบรรจุกล่องในรถบรรทุกที่แต่ละกล่องต้องวางในช่วงเวลาที่กำหนด ทำให้เกิดพื้นที่ว่างระหว่างกล่อง ช่องว่างเหล่านี้จะเพิ่มขึ้นอย่างรวดเร็วเมื่อคุณต้องจัดการกับองค์ประกอบของอาเรย์หลายพันตัว

ข้อจำกัดการจัดตำแหน่ง: กฎที่กำหนดให้ข้อมูลต้องถูกจัดเก็บที่ที่อยู่หน่วยความจำเฉพาะเพื่อการเข้าถึงของโปรเซสเซอร์ที่เหมาะสมที่สุด

ชุมชนอภิปรายเรื่องแนวทางแก้ไขแบบง่ายเทียบกับแบบเหมาะสมที่สุด

ชุมชนโปรแกรมเมอร์ได้อภิปรายกันว่า Lua ควรใช้การแก้ไขแบบง่ายๆ หรือการปรับปรุงที่ซับซ้อนกว่า นักพัฒนาบางคนชี้ให้เห็นว่าแอตทริบิวต์คอมไพเลอร์ที่เรียกว่า __attribute__((packed)) สามารถแก้ปัญหาได้ทันที ลดการใช้หน่วยความจำจาก 16 ไบต์เป็น 9 ไบต์ต่อค่าโดยไม่สูญเสียประสิทธิภาพ

อย่างไรก็ตาม ผู้ดูแล Lua ให้ความสำคัญกับความสามารถในการพกพาเหนือสิ่งอื่นใด แอตทริบิวต์นี้ใช้งานได้เฉพาะกับคอมไพเลอร์บางตัวและไม่ใช่ส่วนหนึ่งของ C มาตรฐาน ทำให้ไม่เหมาะสำหรับภาษาที่ออกแบบมาเพื่อทำงานได้ทุกที่ตั้งแต่เซิร์ฟเวอร์ระดับสูงไปจนถึงไมโครคอนโทรลเลอร์พื้นฐาน

การอภิปรายนี้เน้นย้ำถึงความตึงเครียดพื้นฐานในการออกแบบภาษาระหว่างการปรับปรุงและความเข้ากันได้ ดังที่สมาชิกชุมชนคนหนึ่งกล่าวไว้ ฐานผู้ใช้ของ Lua รวมถึงระบบฝังตัวจำนวนมากที่มีฮาร์ดแวร์ที่ไม่ปกติและคอมไพเลอร์รุ่นเก่าที่ไม่รองรับส่วนขยายสมัยใหม่

การเปรียบเทียบโซลูชันที่เสนอ:

  • Packed attribute: ลดขนาดจาก 16 เป็น 9 ไบต์ แต่ไม่สามารถพกพาได้
  • Parallel arrays: กำจัด padding ทั้งหมด รักษาความสามารถในการพกพา
  • Reflected arrays: ไม่มีการสูญเสีย padding เลย ไม่มีโอเวอร์เฮดเพิ่มเติมสำหรับอาร์เรย์ขนาดเล็ก
  • Homogeneous arrays: แท็กประเภทเดียวต่ออาร์เรย์ แต่เพิ่มความซับซ้อน

แนวทางแก้ไขที่ชนะ: Reflected Arrays

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

แทนที่จะเก็บแต่ละค่าไว้ข้างๆ แท็กของมัน ระบบจะจัดเก็บค่าทั้งหมดไว้ด้วยกันในบล็อกหนึ่งและแท็กทั้งหมดไว้ด้วยกันในอีกบล็อกหนึ่ง เมื่อโปรแกรมต้องการเข้าถึงองค์ประกอบของอาเรย์ มันจะดึงค่าจากตำแหน่งหนึ่งและแท็กจากตำแหน่งที่สอดคล้องกันในอาเรย์แท็ก

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

ผลกระทบในโลกจริงต่อแอปพลิเคชัน

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

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

แม้ว่ารายละเอียดทางเทคนิคอาจดูเป็นนามธรรม แต่ผลกระทบในทางปฏิบัติก็ตรงไปตรงมา: โปรแกรม Lua จะใช้หน่วยความจำน้อยลงในขณะที่ทำงานได้เร็วเท่าเดิม ทำให้ภาษานี้น่าสนใจยิ่งขึ้นสำหรับแอปพลิเคชันที่ต้องการทรัพยากรอย่างละเอียดอ่อน

อ้างอิง: Compact Representations for Arrays in Lua