ใช้ประโยชน์จากการมัลติเธรดระหว่างเกมลูปและ openGL


10

การพูดคุยในบริบทของเกมโดยใช้ openGL renderer:

สมมติว่ามีสองหัวข้อ:

  1. อัพเดทตรรกะของเกมและฟิสิกส์เป็นต้นสำหรับในเกมวัตถุ

  2. ทำให้ openGL ดึงสายสำหรับแต่ละวัตถุในเกมตามข้อมูลในวัตถุในเกม (เธรด 1 นั้นทำการปรับปรุงอยู่เสมอ)

ยกเว้นว่าคุณมีสองสำเนาของวัตถุแต่ละเกมในสถานะปัจจุบันของเกมคุณจะต้องหยุดเธรด 1 ในขณะที่เธรด 2 ทำการเรียกการดึงมิฉะนั้นวัตถุในเกมจะได้รับการอัปเดตในช่วงกลางของการดึงการดึงสำหรับวัตถุนั้น ไม่พึงประสงค์!

แต่การหยุดเธรด 1 เพื่อโทรออกอย่างปลอดภัยจากเธรด 2 ฆ่าวัตถุประสงค์ทั้งหมดของการทำงานหลายเธรด / การทำงานพร้อมกัน

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

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

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


1. สมมติว่ามีเพียงสองเธรดที่ไม่ได้ปรับขนาดได้ 4 คอร์เป็นเรื่องธรรมดามากและจะเพิ่มขึ้นเท่านั้น 2. คำตอบกลยุทธ์การปฏิบัติที่ดีที่สุด: ใช้การแยกส่วนคำสั่งแบบสอบถามความรับผิดชอบและระบบรุ่น / ส่วนประกอบของนักแสดง 3. คำตอบที่สมจริง: เพียงแค่แฮ็คมันด้วยวิธี C ++ แบบดั้งเดิมด้วยการล็อคและสิ่งของ
Den

ที่เก็บข้อมูลทั่วไปหนึ่งรายการหนึ่งล็อก
Justin

@ เพียงแค่ฉันบอกด้วยล็อคซิงค์ข้อได้เปรียบเพียงอย่างเดียวของ multithreading จะถูกฆ่าอย่างไร้ความปราณีในเวลากลางวันเธรดการอัปเดตจะต้องรอจนกระทั่งวาดเธรดทำการเรียกใช้วัตถุทั้งหมดจากนั้นเธรดการวาดจะรอจนกว่าห่วงการอัปเดตจะเสร็จสิ้น ! ซึ่งเลวร้ายยิ่งกว่าวิธีการเธรดเดียว
Allahjane

1
ดูเหมือนว่าวิธีการแบบมัลติเธรดในเกมที่มี async graphics api (เช่น openGL) ยังคงเป็นหัวข้อที่ใช้งานอยู่และไม่มีมาตรฐานหรือวิธีแก้ปัญหาที่สมบูรณ์แบบนี้
Allahjane

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

คำตอบ:


13

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

มีหลายทางเลือกในการแก้ปัญหานี้หนึ่งโซลูชั่นที่นิยมสำหรับการแสดงผลแบบมัลติเธรดคือการใช้บัฟเฟอร์สองเท่าของคำสั่ง สิ่งนี้ประกอบด้วยการเรียกใช้ renderer back-end ในเธรดแยกต่างหากโดยที่การเรียกการวาดและการสื่อสารด้วย API การเรนเดอร์ทั้งหมดจะดำเนินการ เธรด Front-End ที่รันลอจิกเกมสื่อสารกับตัวแสดงผลส่วนหลังผ่านบัฟเฟอร์คำสั่ง (บัฟเฟอร์สองครั้ง). ด้วยการตั้งค่านี้คุณจะมีจุดประสานเพียงจุดเดียวที่เสร็จสิ้นเฟรม ในขณะที่ Front-End กำลังเติมบัฟเฟอร์หนึ่งด้วยคำสั่ง render ส่วนแบ็คเอนด์นั้นใช้อีกบัฟเฟอร์ หากเธรดทั้งสองมีความสมดุลกันอย่างดีไม่ควรอดอาหาร วิธีการนี้เป็นวิธีที่ไม่ดีนักเนื่องจากมันมีความหน่วงแฝงในเฟรมเรนเดอร์และโปรแกรมควบคุม OpenGL มีแนวโน้มที่จะทำสิ่งนี้ในกระบวนการของตัวเองดังนั้นการเพิ่มประสิทธิภาพจะต้องมีการวัดอย่างรอบคอบ นอกจากนี้ยังใช้เพียงสองแกนเท่านั้น วิธีการนี้ใช้ในเกมที่ประสบความสำเร็จหลายเกมเช่นDoom 3และQuake 3

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

ในที่สุดฉันขอแนะนำให้อ่าน:


แค่สงสัย! คุณรู้จัก Doom 3 ใช้วิธีนี้ได้อย่างไร ฉันคิดว่านักพัฒนาซอฟต์แวร์จะไม่ยอมแพ้!
Allahjane

4
@Allahjane, Doom 3 เป็นโอเพนซอร์ส ในลิงก์ที่ฉันให้ไว้คุณจะพบรีวิวโครงสร้างโดยรวมของเกม และคุณจะเข้าใจผิดใช่มันเป็นเรื่องยากที่จะหาเกมอย่างเต็มที่มาเปิด แต่นักพัฒนามักจะเปิดเผยเทคนิคและเทคนิคของพวกเขาในบล็อกเอกสารและเหตุการณ์เช่นGDC
glampert

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