ติดตั้ง
ฉันมีสถาปัตยกรรมเอนทิตีคอมโพเนนต์ที่เอนทิตีสามารถมีชุดของคุณลักษณะ (ซึ่งเป็นข้อมูลที่บริสุทธิ์โดยไม่มีพฤติกรรม) และมีระบบที่ใช้ตรรกะเอนทิตีซึ่งทำงานกับข้อมูลนั้น เป็นหลักในรหัสหลอกบ้าง:
Entity
{
id;
map<id_type, Attribute> attributes;
}
System
{
update();
vector<Entity> entities;
}
ระบบที่เพิ่งเคลื่อนที่ไปตามเอนทิตีทั้งหมดในอัตราคงที่อาจเป็น
MovementSystem extends System
{
update()
{
for each entity in entities
position = entity.attributes["position"];
position += vec3(1,1,1);
}
}
เป็นหลักฉันพยายามขนาน update () อย่างมีประสิทธิภาพที่สุด สิ่งนี้สามารถทำได้โดยการรันทั้งระบบในแบบคู่ขนานหรือโดยการให้แต่ละการอัปเดต () ของระบบหนึ่งมีส่วนประกอบสองส่วนเพื่อให้เธรดที่แตกต่างกันสามารถดำเนินการอัปเดตระบบเดียวกันได้ แต่สำหรับชุดย่อยอื่น
ปัญหา
ในกรณีของระบบการเคลื่อนไหวที่แสดงการขนานกันนั้นเป็นเรื่องเล็กน้อย เนื่องจากเอนทิตีไม่ได้พึ่งพาซึ่งกันและกันและไม่แก้ไขข้อมูลที่แชร์เราจึงสามารถย้ายเอนทิตีทั้งหมดในแบบคู่ขนาน
อย่างไรก็ตามบางครั้งระบบเหล่านี้ต้องการให้เอนทิตีโต้ตอบกับ (อ่าน / เขียนข้อมูลจาก / ถึง) ซึ่งกันและกันบางครั้งอยู่ในระบบเดียวกัน แต่บ่อยครั้งระหว่างระบบต่าง ๆ ที่ขึ้นอยู่กับแต่ละระบบ
ตัวอย่างเช่นในระบบฟิสิกส์บางครั้งเอนทิตีอาจโต้ตอบกัน วัตถุสองรายการชนกันตำแหน่งตำแหน่งความเร็วและคุณลักษณะอื่น ๆ จะถูกอ่านจากพวกเขาได้รับการอัปเดตแล้วแอตทริบิวต์ที่อัปเดตจะถูกเขียนกลับไปที่เอนทิตีทั้งสอง
และก่อนที่ระบบเรนเดอร์ในเครื่องยนต์สามารถเริ่มเรนเดอร์เอนทิตีได้มันต้องรอให้ระบบอื่นทำการประมวลผลให้เสร็จ
หากเราพยายามที่จะทำให้ขนานนี้มันจะนำไปสู่สภาพการแข่งขันแบบคลาสสิกที่ระบบต่าง ๆ อาจอ่านและแก้ไขข้อมูลในเวลาเดียวกัน
จะเป็นการดีที่จะมีวิธีแก้ปัญหาที่ระบบทั้งหมดอาจอ่านข้อมูลจากเอนทิตีที่ต้องการโดยไม่ต้องกังวลเกี่ยวกับระบบอื่น ๆ ที่แก้ไขข้อมูลเดียวกันในเวลาเดียวกัน ระบบเหล่านี้ด้วยตนเอง (ซึ่งบางครั้งอาจไม่สามารถทำได้)
ในการใช้งานขั้นพื้นฐานสิ่งนี้สามารถทำได้โดยเพียงแค่การอ่านและเขียนข้อมูลทั้งหมดในส่วนที่สำคัญ (ปกป้องพวกเขาด้วย mutexes) แต่นี่จะทำให้เกิดโอเวอร์เฮดของรันไทม์จำนวนมากและอาจไม่เหมาะสำหรับแอปพลิเคชันที่มีประสิทธิภาพสูง
สารละลาย?
ในความคิดของฉันทางออกที่เป็นไปได้คือระบบที่อ่าน / อัปเดตและเขียนข้อมูลแยกจากกันดังนั้นในระยะที่มีค่าใช้จ่ายสูงระบบจะอ่านข้อมูลเท่านั้นและคำนวณสิ่งที่พวกเขาต้องการคำนวณคำนวณผลลัพธ์จากนั้นจึงเขียนทั้งหมด ข้อมูลที่เปลี่ยนแปลงกลับไปยังเอนทิตีเป้าหมายในการเขียนที่แยกต่างหาก ระบบทั้งหมดจะดำเนินการกับข้อมูลในสถานะที่เป็นในตอนเริ่มต้นของเฟรมและจากนั้นก่อนสิ้นเฟรมเมื่อระบบทั้งหมดเสร็จสิ้นการปรับปรุงการส่งการเขียนแบบอนุกรมจะเกิดขึ้นเมื่อผลลัพธ์ที่แคชต่างกันทั้งหมด ระบบจะวนซ้ำผ่านและเขียนกลับไปยังเอนทิตีเป้าหมาย
สิ่งนี้ขึ้นอยู่กับแนวคิด (อาจผิดหรือเปล่า?) ว่าการชนะอย่างเท่าเทียมกันอย่างง่ายนั้นอาจใหญ่พอที่จะเอาชนะต้นทุนได้ (ทั้งในแง่ของประสิทธิภาพการทำงานของรันไทม์และค่าใช้จ่ายในการเขียนโค้ด) ของการแคชผลลัพธ์
คำถาม
ระบบดังกล่าวจะนำไปใช้อย่างไรเพื่อให้ได้ประสิทธิภาพสูงสุด? รายละเอียดการนำไปปฏิบัติของระบบดังกล่าวคืออะไรและมีข้อกำหนดเบื้องต้นสำหรับระบบ Entity-Component ที่ต้องการใช้โซลูชันนี้อย่างไร