การปรับปรุงหน่วยความจำ C Struct ก่อให้เกิดการอภิปรายเรื่องกฎการจัดตำแหน่งและเครื่องมือสำหรับนักพัฒนา

ทีมชุมชน BigGo
การปรับปรุงหน่วยความจำ C Struct ก่อให้เกิดการอภิปรายเรื่องกฎการจัดตำแหน่งและเครื่องมือสำหรับนักพัฒนา

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

ผลลัพธ์การปรับปรุงหน่วยความจำ

  • ขนาด struct เดิม: 96 ไบต์
  • หลังจากจัดเรียงฟิลด์ใหม่: 92 ไบต์ (ลดลง 4 ไบต์)
  • หลังจากลบ derived state: 88 ไบต์
  • หลังจากใช้ integer types ที่เล็กกว่า: 84 ไบต์
  • หลังจากใช้ bitfields: 80 ไบต์
  • หลังจากใช้ enum สำหรับชื่อ: 20 ไบต์
  • การลดลงทั้งหมด: 76 ไบต์ (เล็กลง 79%)

กฎการจัดตำแหน่งต้องการคำอธิบายที่ชัดเจน

ชุมชนได้เน้นย้ำถึงความไม่ถูกต้องที่สำคัญในการอธิบายการจัดตำแหน่งหน่วยความจำในบทความต้นฉบับ แม้ว่าบทความจะแนะนำว่า CPU ต้องการหน่วยความจำที่จัดตำแหน่งในชุด 4 ไบต์เป็นกฎทั่วไป แต่นักพัฒนาชี้ให้เห็นว่าสิ่งนี้ทำให้ความเป็นจริงง่ายเกินไป ชนิดข้อมูลแต่ละประเภทจริงๆ แล้วมีข้อกำหนดการจัดตำแหน่งเฉพาะของตัวเอง - ตยอางเช่น bool และ char มักจะจัดตำแหน่งที่ 1 ไบต์ short ที่ 2 ไบต์ และ int ที่ 4 ไบต์ การจัดตำแหน่งโดยรวมของ struct จะกลายเป็นการจัดตำแหน่งสูงสุดของชนิดสมาชิกทั้งหมด ไม่ใช่ข้อกำหนด 4 ไบต์คงที่

ความแตกต่างนี้มีความสำคัญอย่างมากสำหรับนักพัฒนาที่ทำงานบนสถาปัตยกรรมต่างๆ การขยายฟิลด์ int เป็น long อาจเพิ่มการจัดตำแหน่งเป็น 8 ไบต์ใน CPU บางตัว ในขณะที่การลบฟิลด์ int และ float ทั้งหมดจะลดการจัดตำแหน่งเป็น 1 ไบต์ในระบบส่วนใหญ่

ข้อกำหนดการจัดตำแหน่งของประเภทข้อมูล

  • bool/char: การจัดตำแหน่งแบบ 1 ไบต์
  • short: การจัดตำแหน่งแบบ 2 ไบต์
  • int: การจัดตำแหน่งแบบ 4 ไบต์
  • long: การจัดตำแหน่งแบบ 8 ไบต์ (ใน CPU บางรุ่น)
  • float: การจัดตำแหน่งแบบ 4 ไบต์
  • การจัดตำแหน่งของ Struct = การจัดตำแหน่งสูงสุดของประเภทสมาชิก

เครื่องมือระดับมืออาชีพสำหรับการวิเคราะห์ Struct

การอภิปรายเผยให้เห็นว่านักพัฒนาระดับมืออาชีพ โดยเฉพาะผู้ที่ทำงานกับ Linux kernel พึ่งพาเครื่องมือเฉพาะทางมากกว่าการคำนวณด้วยตนเอง เครื่องมือ pahole จากแพ็กเกจ dwarves โดดเด่นเป็นโซลูชันมาตรฐานที่นักพัฒนา kernel ใช้สำหรับการวิเคราะห์เค้าโครง struct และระบุโอกาสในการปรับปรุง เครื่องมือนี้แสดง padding การจัดตำแหน่ง และแนะนำการปรับปรุงโดยอัตโนมัติ - ซึ่งเป็นข้อได้เปรียบที่สำคัญเหนือวิธีการด้วยตนเองที่อธิบายในบทความต้นฉบับ

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

การใช้งานที่กว้างขึ้นและคุณสมบัติของภาษาสมัยใหม่

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

มาตรฐานภาษาสมัยใหม่ยังขยายตัวเลือกสำหรับนักพัฒนา C23 แนะนำ _Float16 สำหรับชนิดจุดทศนิยมที่เล็กกว่า ในขณะที่ C++ เสนอตัวเลือก float16_t และ bfloat16_t การเพิ่มเติมเหล่านี้ให้การควบคุมการใช้หน่วยความจำที่ละเอียดมากขึ้น ซึ่งสำคัญโดยเฉพาะสำหรับแอปพลิเคชันที่มีข้อจำกัดหน่วยความจำที่เข้มงวด

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

อ้างอิง: Writing memory efficient C structs