ฉันกำลังสร้างเอ็นจิ้นเกม 2D ง่าย ๆ และฉันต้องการอัปเดตและแสดงสไปรต์ในชุดข้อความต่างๆเพื่อเรียนรู้วิธีการทำงาน
ฉันต้องการซิงโครไนซ์เธรดการอัพเดทและเรนเดอร์หนึ่ง ปัจจุบันฉันใช้แฟล็กอะตอมสองอัน เวิร์กโฟลว์มีลักษณะดังนี้:
Thread 1 -------------------------- Thread 2
Update obj ------------------------ wait for swap
Create queue ---------------------- render the queue
Wait for render ------------------- notify render done
Swap render queues ---------------- notify swap done
ในการตั้งค่านี้ฉัน จำกัด FPS ของเธรดการแสดงผลเป็น FPS ของเธรดการปรับปรุง นอกจากนี้ฉันใช้sleep()
เพื่อ จำกัด ทั้งเรนเดอร์และอัปเดต FPS ของเธรดเป็น 60 ดังนั้นฟังก์ชั่นรอทั้งสองจะไม่รอเวลามาก
ปัญหาคือ:
การใช้งาน CPU โดยเฉลี่ยอยู่ที่ประมาณ 0.1% บางครั้งมันสูงถึง 25% (ในพีซีแบบ quad core) หมายความว่าเธรดกำลังรอเธรดอื่นเนื่องจากฟังก์ชัน wait เป็น while loop พร้อมกับการทดสอบและการตั้งค่าการทำงานและ a while loop จะใช้ทรัพยากร CPU ทั้งหมดของคุณ
คำถามแรกของฉันคือมีวิธีอื่นในการซิงโครไนซ์เธรดทั้งสองหรือไม่ ฉันสังเกตเห็นว่าstd::mutex::lock
ไม่ใช้ CPU ในขณะที่รอการล็อคทรัพยากรดังนั้นจึงไม่ใช่การวนรอบสักครู่ มันทำงานยังไง? ฉันไม่สามารถใช้std::mutex
เพราะฉันจะต้องล็อคพวกเขาในหนึ่งกระทู้และปลดล็อคในหัวข้ออื่น
คำถามอื่น ๆ คือ; เนื่องจากโปรแกรมรันที่ 60 FPS ทำไมบางครั้งการใช้งาน CPU ถึง 25% หมายความว่าหนึ่งในสองการรอนั้นรออยู่มาก (ทั้งสองเธรดนั้น จำกัด ไว้ที่ 60fps ดังนั้นจึงไม่จำเป็นต้องทำการซิงโครไนซ์มากนัก)
แก้ไข: ขอบคุณสำหรับคำตอบทั้งหมด ก่อนอื่นฉันอยากจะบอกว่าฉันไม่ได้เริ่มหัวข้อใหม่ในแต่ละเฟรมเพื่อเรนเดอร์ ฉันเริ่มต้นทั้งการอัพเดตและเรนเดอร์ลูปที่จุดเริ่มต้น ฉันคิดว่าการมัลติเธรดสามารถประหยัดเวลา: ฉันมีฟังก์ชั่นต่อไปนี้: FastAlg () และ Alg () Alg () เป็นทั้ง obj Update ของฉันและ render obj และ Fastalg () คือ "คิวการแสดงผลส่งไปยัง" renderer "ของฉัน ในหัวข้อเดียว:
Alg() //update
FastAgl()
Alg() //render
ในสองหัวข้อ:
Alg() //update while Alg() //render last frame
FastAlg()
ดังนั้นการมัลติเธรดอาจช่วยให้ประหยัดได้ในเวลาเดียวกัน (อันที่จริงแล้วในแอปพลิเคชันทางคณิตศาสตร์อย่างง่ายที่จะทำได้โดยที่ alg เป็นอัลกอริธึมที่ยาวและรวดเร็วขึ้นอีกอัน)
ฉันรู้ว่าการนอนไม่ได้เป็นความคิดที่ดี แต่ฉันไม่เคยมีปัญหา จะดีกว่านี้ไหม
While(true)
{
If(timer.gettimefromlastcall() >= 1/fps)
Do_update()
}
แต่นี่จะไม่มีที่สิ้นสุดในขณะที่วนรอบที่จะใช้ CPU ทั้งหมด ฉันสามารถใช้โหมดสลีป (หมายเลข <15) เพื่อ จำกัด การใช้งานได้หรือไม่ ด้วยวิธีนี้มันจะทำงานที่ 100 fps และฟังก์ชั่นอัพเดทจะถูกเรียกเพียง 60 ครั้งต่อวินาที
ในการซิงโครไนซ์เธรดทั้งสองฉันจะใช้ waitforsingleobject กับ createSemaphore ดังนั้นฉันจะสามารถล็อคและปลดล็อกในเธรดที่แตกต่างกันได้ (whitout โดยใช้ลูป while) ใช่ไหม