การใช้ Sleep () ใน Game loop (บน Windows) ปลอดภัยหรือไม่?


27

การใช้ฟังก์ชั่น Sleep () บน Windows ใน Game loop (C ++) ปลอดภัยหรือไม่? ฉันต้องการให้เฟรมเรทคงที่


คุณต้องชี้แจงว่า "ปลอดภัย" หมายความว่าอะไร แน่นอนว่ามันปลอดภัยและจะไม่ทำลายหน่วยความจำหรือทำให้พีซีของผู้เล่นเสียหาย
Kromster พูดว่าสนับสนุน Monica

คำตอบ:


32

ไม่มันไม่ใช่. การนอนหลับรับประกันได้ว่าจะให้เวลาขั้นต่ำในการนอนหลับเท่านั้น ความละเอียดของตัวจับเวลาของคุณ (ตั้งค่าผ่าน timeBeginPeriod) ก็มีความสำคัญเช่นกันและแม้ว่าคุณจะใช้อย่างอื่น (เช่น QueryPerformanceCounter) สำหรับตัวจับเวลาของคุณ

ดังนั้นโดยสรุป:

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

กรณีที่เหมาะสมเพียงอย่างเดียวในการใช้ Sleep คือถ้าคุณต้องการลดการใช้งาน CPU สำหรับอุปกรณ์มือถือ แม้ว่าคุณจะใช้โหมดสลีป (1); การใช้มันเพื่อควบคุม framerates ไม่ใช่วิธีที่จะไป

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

ในเวลานี้จำเป็นต้องพูดถึงบทความนี้: Gaffer On Games - Fix Timestep ของคุณ! . ที่อธิบายถึงขั้นตอนที่คุณต้องได้รับการประทับเวลาที่สอดคล้องกันในการจำลองของคุณ


ขอบคุณมากสำหรับการเชื่อมโยง จนถึงตอนนี้ฉันมักจะใช้วิธี "การเปลี่ยนแปลงเวลา" ที่อธิบายไว้ในบทความ
Ivan Vučica

การนอนหลับยังเป็นอันตรายต่อเครื่องที่เปิดใช้งาน Intel speed step-step
waterwizard11

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

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

1
ควรกล่าวถึงฉันคิดว่านี่จะเกี่ยวข้องกับ "... ถ้าคุณต้องการลดการใช้งาน CPU ... ": nanobit.net/doxy/quake3/win__main_8c-source.html <- รหัสที่เกี่ยวข้องเริ่มต้นที่ 01224
user_123abc

16

คำตอบสั้น ๆ : ไม่มันไม่ใช่

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

GLUT จัดเตรียมglutTimerFunc ()ซึ่งถ้าคุณกำลังเขียนโปรแกรมใน OpenGL ฟังก์ชั่นที่เหมาะสมที่คุณต้องการ ลองดูที่ตัวอย่างนี้หรือนี้อย่างใดอย่างหนึ่ง


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