รูปแบบการจัดสรรหน่วยความจำที่ใช้ในการพัฒนาเกม


20

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

ฉันสามารถใช้เทคนิคการจัดสรรหน่วยความจำแบบใดและทำไมจึงเป็นเทคนิคที่ดี


1
คุณต้องการจริงๆเหรอ? เป็นเพียงหนึ่งในสิ่งที่ซับซ้อนที่สุดที่ทีมสามารถนำไปใช้ได้หากพวกเขาสามารถนำไปปฏิบัติได้
Ali1S232

4
มันเป็นเรื่องที่น่าสนใจสำหรับฉันดังนั้นฉันอยากจะเรียนรู้เกี่ยวกับมันและทำให้สำเร็จ
chadb

ฉันต้องบอกว่าหัวเรื่องเป็นเรื่องที่น่าสนใจจริงๆ ... มีหลายกรณีที่อาจหมายถึงการจัดสรร แต่สำหรับเกมพีซีโดยเฉลี่ยคุณค่อนข้างกังวลเกี่ยวกับเกมจริง ...
rioki

คุณได้วิจัยซอร์สโค้ดสำหรับ malloc ไลบรารีมาตรฐานที่ทันสมัยและฟรีหรือใหม่และลบหรือไม่ ฉันถามเพราะดูเหมือนว่าจะให้พื้นฐานที่มีประโยชน์มากกับการเปรียบเทียบกลยุทธ์การจัดสรรทางเลือกใด ๆ กับอัลกอริทึมหรือในทางปฏิบัติ ดูเหมือนว่ามันจะให้ข้อมูลเชิงลึกที่แท้จริงเกี่ยวกับสิ่งที่คุณจะได้รับ
Louis Langholtz

คำตอบ:


25

Game Engine Architectureมีข้อมูลบางอย่างเกี่ยวกับหัวข้อนี้ พื้นฐานคือคุณต้องทำการวิเคราะห์เพื่อทำความเข้าใจความต้องการหน่วยความจำของคุณต่อระดับ / เฟรม / ฯลฯ เป็นเหมือน แต่มีรูปแบบบางอย่างที่ผู้เขียนกล่าวถึงเมื่อเห็นหลายครั้ง:

  • ตัวจัดสรรแบบกองซ้อน: จัดสรรส่วนหน่วยความจำขนาดใหญ่หนึ่งครั้งจากนั้นจัดสรรตัวชี้ภายในบล็อกหน่วยความจำนั้นเพื่อตอบสนองคำขอจากที่อื่นในเกม สิ่งนี้มีประโยชน์ในการหลีกเลี่ยงการสลับบริบทที่ต้องการโดยการจัดสรรหน่วยความจำและเนื่องจากคุณสามารถใช้เทคนิคของคุณเองในการบังคับใช้ความต่อเนื่องหรือการจัดตำแหน่งเฉพาะสำหรับการดำเนินการ SIMD เอ็นจินบางตัวยังใช้สแต็กสิ้นสุดสองครั้งที่โหลดทรัพยากรประเภทหนึ่งจากด้านบนและอีกประเภทหนึ่งถูกโหลดจากด้านล่าง บางที LSR (Load and Stay Resident ซึ่งเป็นประเภทที่ต้องการตลอดทั้งเกมของคุณ) จากด้านบนและข้อมูลต่อระดับจากด้านล่าง
  • หน่วยความจำเฟรมเดี่ยวหรือหน่วยความจำเฟรมแบบบัฟเฟอร์คู่: หน่วยความจำสำหรับการดำเนินการที่เกิดขึ้นภายในหนึ่งหรือสองรอบเฟรม สิ่งนี้มีประโยชน์เพราะแทนที่จะต้องจัดสรร / ยกเลิกการจัดสรรทุกเฟรมคุณสามารถกระจายข้อมูลเฟรมสุดท้ายโดยการรีเซ็ตตัวชี้ที่คุณใช้เพื่อติดตามหน่วยความจำไปยังจุดเริ่มต้นของบล็อก
  • Object Pools: บล็อกของหน่วยความจำสำหรับวัตถุขนาดเดียวกันจำนวนมากเช่นอนุภาคศัตรูขีปนาวุธ สิ่งเหล่านี้มีประโยชน์เพราะคุณสามารถประสบความสำเร็จได้อย่างง่ายดายด้วยการค้นหากลุ่มที่ไม่ได้ใช้ครั้งแรกในกลุ่มของคุณ พวกมันยังทำให้การวนซ้ำง่ายขึ้นเพราะแต่ละวัตถุอยู่ในช่วงออฟเซ็ตที่รู้จักจากครั้งสุดท้าย

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

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


1

จากสิ่งที่ฉันได้เห็น (แต่ไม่ได้ทำ) แต่ละเกมมีแนวโน้มที่จะสืบทอดกลไกการจัดสรรจากเฟรมเวิร์กจากเอ็นจิ้นเกมจากเวอร์ชันก่อนหน้า (2010 -> 2011) หรือได้รับชุดใหม่ที่เขียนขึ้นมาโดยเฉพาะ โครงสร้าง (ทั้งเมื่อโครงสร้างข้อมูลสามารถนำมาใช้ใหม่และขนาดคงที่หรือหลายประเภทและขนาดตัวแปร)

นอกจากนี้เรามีผู้จัดสรรที่แตกต่างกันสำหรับไฟล์เสียง / ส่วนประกอบกว่าระดับและวัตถุเกมอื่น ๆ ในโครงการเดียวกัน ในตัวจัดสรรโครงการอื่น ๆ นั้นสืบทอดมาจากไลบรารีภายนอกสำหรับส่วนประกอบที่จัดการโดย lib นั้นเท่านั้น

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

ตัวอย่างที่เกี่ยวข้องกับคุณควรเริ่มต้นด้วยการดูที่ตัวเกมOGRE 3Dมันมีตัวเลือกไม่กี่ตัวในการกำหนดค่าตัวจัดสรรหน่วยความจำ


0

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

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

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

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

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.