0Pricing
C++ Academy · บทเรียน

โครงสร้างข้อมูลที่เป็นมิตรต่อแคช

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

โครงสร้างข้อมูลที่เป็นมิตรต่อแคช เป็นบทเรียน C++ Academy ฟรีบน CoddyKit นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน คุณสามารถอ่านบทเรียนทั้งหมดด้านล่างฟรี — จากนั้นลองปฏิบัติด้วยตัวคุณเองในเบราว์เซอร์พร้อมตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7 บทเรียนนี้เป็นส่วนหนึ่งของเส้นทางการเรียน C++ Academy และความก้าวหน้าของคุณจะซิงค์ข้ามเว็บและแอป CoddyKit คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

ลำดับชั้นของหน่วยความจำ

CPU มีแคชหลายระดับ (L1, L2, L3) ซึ่งเร็วกว่าหน่วยความจำหลักมาก โค้ดที่ใช้แคชได้ดีจะเก็บข้อมูลที่ใช้งานอยู่ใกล้กับ CPU

บรรทัดแคช

หน่วยความจำจะถูกดึงมาเป็น บรรทัดแคช ซึ่งโดยทั่วไปมีขนาด 64 ไบต์ การอ่านหนึ่งไบต์จะโหลดทั้งบรรทัด ใช้ประโยชน์จากพฤติกรรมนี้

ความเป็นท้องถิ่นของการอ้างอิง

มีคุณสมบัติสำคัญสองประการ:

  • ความเป็นท้องถิ่นเชิงพื้นที่ — ใช้หน่วยความจำบริเวณใกล้เคียงในเวลาไม่นาน
  • ความเป็นท้องถิ่นเชิงเวลา — ใช้หน่วยความจำเดิมซ้ำในเวลาไม่นาน

แบบต่อเนื่องเทียบกับแบบเชื่อมโยง

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

// Cache friendly
std::vector<int> v(1000);
for (auto& x : v) ++x;

// Cache UNfriendly
std::list<int> l(1000);
for (auto& x : l) ++x;

AoS เทียบกับ SoA

โครงร่างสองแบบสำหรับอาร์เรย์ของระเบียน:

  • AoS (อาร์เรย์ของโครงสร้าง) — เป็นธรรมชาติ แต่การวนดูฟิลด์เดียวจะสัมผัสฟิลด์ทั้งหมด
  • SoA (โครงสร้างของอาร์เรย์) — เหมาะกว่าเมื่อการวนส่วนใหญ่ใช้เพียงบางฟิลด์
// AoS
struct Particle { float x, y, z, vx, vy, vz; };
std::vector<Particle> particles;

// SoA
struct Particles {
    std::vector<float> x, y, z, vx, vy, vz;
};

การจัดวางสมาชิกในโครงสร้าง

เรียงสมาชิกจากใหญ่ไปเล็กเพื่อลดไบต์เติมให้เหลือน้อยที่สุด เครื่องมืออย่าง pahole จะแสดงโครงร่างจริง

struct Bad  { char c; double d; char c2; };  // padded
struct Good { double d; char c; char c2; };  // smaller

การใช้ข้อมูลร่วมกันปลอม

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

struct alignas(64) Counter {
    std::atomic<int> value;
};

การแยกข้อมูลร้อนและเย็น

แยกข้อมูลร้อน ซึ่งเข้าถึงบ่อย ออกจากข้อมูลเย็น ซึ่งเข้าถึงไม่บ่อย ไปไว้ในโครงสร้างคนละชุด CPU จะแคชเฉพาะส่วนที่ร้อน

การจัดสรรล่วงหน้า

จัดสรรเวกเตอร์ล่วงหน้าด้วย reserve เพื่อหลีกเลี่ยงการจัดสรรใหม่ซ้ำ ๆ การจัดสรรใหม่แต่ละครั้งจะคัดลอกสมาชิกทั้งหมด ซึ่งมีค่าใช้จ่ายสูงและทำให้แคชสูญเสียประสิทธิภาพ

การเข้าถึงตามลำดับนั้นเร็วกว่า

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

หลีกเลี่ยงการอ้อมผ่านพอยน์เตอร์

พอยน์เตอร์บังคับให้ CPU ไล่ตามความสัมพันธ์ของข้อมูล std::vector<T*> ช้ากว่า std::vector<T> เมื่อต้องวนดูข้อมูล ใช้การอ้อมผ่านพอยน์เตอร์เฉพาะเมื่อจำเป็น

ทำโปรไฟล์ก่อนปรับให้เหมาะสม

คำว่า “ใช้แคชได้ดี” เป็นแนวทาง ไม่ใช่กฎตายตัว วัดผลด้วยเครื่องมืออย่าง perf หรือ VTune เพื่อดูว่าการพลาดแคชส่งผลเสียที่ใด แล้วจึงปรับให้เหมาะสม

ตรวจสอบความเข้าใจ

เหตุใดการวนดู std::vector จึงมักเร็วกว่าอย่างมากเมื่อเทียบกับการวนดู std::list ที่มีขนาดเท่ากัน

สรุป

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

คำถามที่พบบ่อย

บทเรียน “โครงสร้างข้อมูลที่เป็นมิตรต่อแคช” ฟรีหรือไม่

ใช่ — ข้อความเต็มของ “โครงสร้างข้อมูลที่เป็นมิตรต่อแคช” ฟรีให้อ่านที่นี่บนเว็บ เพื่อปฏิบัติแบบโต้ตอบ (ตัวแก้ไขโค้ดในตัวและติวเตอร์ AI ตลอด 24/7) และปลดล็อคส่วนที่เหลือของคอร์ส C++ Academy ให้อัปเกรดเป็น CoddyKit PRO คอร์ส C++ Academy มีบทเรียนทั้งหมด 4 บทเรียน

คุณจะเรียนรู้อะไรในบทเรียน “โครงสร้างข้อมูลที่เป็นมิตรต่อแคช”

ออกแบบโครงสร้างแบบอาร์เรย์และจัดแพ็กข้อมูลเพื่อให้ใช้แคชได้ใกล้เคียงกัน คุณปฏิบัติ C++ Academy ด้วยโค้ดที่ใช้งานได้จริงที่คุณเรียกใช้โดยตรงในเบราว์เซอร์ และติวเตอร์ AI ตลอด 24/7 ตอบคำถามของคุณขณะที่คุณไปผ่านบทเรียน

คุณต้องมีประสบการณ์ก่อนที่จะเริ่มเรียน C++ Academy หรือไม่

ไม่จำเป็นต้องมีประสบการณ์มาก่อน C++ Academy บน CoddyKit ออกแบบมาสำหรับผู้เริ่มต้นไปจนถึงผู้เรียนขั้นสูง คุณสามารถเริ่มต้นที่นี่หรือเริ่มจากตัวแรกและเรียนด้วยความเร็วของคุณเอง นี่คือบทเรียนที่ 1 จากทั้งหมด 4 บทเรียน

บทเรียน “โครงสร้างข้อมูลที่เป็นมิตรต่อแคช” ใช้เวลานานแค่ไหน

บทเรียน CoddyKit ส่วนใหญ่ใช้เวลาประมาณ 5–10 นาที แต่ละบทเรียนจึงสั้นและเป็นแบบโต้ตอบ คุณสามารถก้าวหน้าอย่างต่อเนื่องและกลับมาเรียนต่อจากตรงที่เพิ่งหยุดบนเว็บและแอปได้เลย

ฉันเขียนและรันโค้ดในบทเรียน C++ Academy นี้ได้ไหม

ได้ บทเรียน C++ Academy ทุกบทมีตัวแก้ไขโค้ดในตัว คุณจึงเขียนและรันโค้ดจริงได้เลยในเบราว์เซอร์ และได้รับข้อเสนอแนะจาก AI ในทันที — ไม่ต้องติดตั้งในเครื่องของคุณ

บทเรียนทั้งหมดในหลักสูตรนี้

  1. โครงสร้างข้อมูลที่เป็นมิตรต่อแคช
  2. การทำนายการแยกแขนงและลูปร้อน
  3. การทำโปรไฟล์ด้วย perf vtune และ Sanitizers
  4. การวัดประสิทธิภาพระดับย่อยด้วย Google Benchmark
← กลับไปที่ C++ Academy