¿Es seguro usar Sleep () en el bucle del juego (en Windows)?

27

¿Es seguro usar la función Sleep () en Windows en el bucle de juego (C ++)? Quiero tener una velocidad de fotogramas fija.

hemogoblin
fuente
Debe aclarar qué quiere decir con "seguro". Por supuesto, es seguro y no va a dañar la memoria ni hacer estallar la PC de los jugadores.
Kromster dice que apoya a Monica el

Respuestas:

32

No, no es. El sueño solo garantiza un tiempo mínimo para dormir, pero en realidad puede dormir por cualquier cantidad de tiempo arbitrario durante ese tiempo. La resolución del temporizador (establecida a través de timeBeginPeriod) también es importante, e incluso si está usando algo más (como QueryPerformanceCounter) para su temporizador, aún necesita timeBeginPeriod para controlar el sueño.

Entonces en resumen:

  • El tiempo para dormir es solo un mínimo garantizado y el tiempo de sueño real puede ser mayor.
  • Sensible al valor establecido (o no establecido) a través de timeBeginPeriod.

El único caso razonable para usar Sleep sería si quisieras reducir el uso de CPU para, por ejemplo, dispositivos móviles. Incluso entonces estarías usando Sleep (1); usarlo para controlar la velocidad de fotogramas no es el camino a seguir.

Forzar vsync es probablemente una forma común de obtener una velocidad de fotogramas fija, pero incluso así, se ejecutará un hardware diferente a diferentes velocidades de actualización y no podrá tener una velocidad de fotogramas fija constante en diferentes máquinas (esto depende de qué tipo de hardware estás apuntando, por supuesto).

En este momento es necesario mencionar este artículo: Gaffer On Games - Fix Your Timestep! . Eso describe los pasos que necesita para obtener un paso de tiempo constante en su simulación.

Maximus Minimus
fuente
Enormes gracias por el enlace. Hasta ahora, solía utilizar el enfoque de "paso de tiempo variable" descrito en el artículo.
Ivan Vučica
La suspensión también es peligrosa en máquinas que tienen habilitado Intel Speed-Step.
waterwizard11
"pero en realidad puede dormir por cualquier cantidad de tiempo arbitrario durante eso". Bueno, eso tiene que ser probado, supongo ... Nunca he visto ninguna prueba de ello, así que supongo que es una de esas 'definiciones'. Sin embargo, es una buena respuesta y sí, no puede (incluso si era, como es, precisa) usar cualquier tipo de suspensión para establecer una velocidad de fotogramas fija (bueno, puede hacerlo, pero necesita un temporizador de alta precisión para hacerlo).
Valmond
2
Según MSDN: "Tenga en cuenta que no se garantiza que un subproceso listo se ejecute inmediatamente. En consecuencia, el subproceso puede no ejecutarse hasta algún tiempo después de que transcurra el intervalo de suspensión". Es cierto, nunca lo he visto suceder, pero al mismo tiempo si está documentado como posible, definitivamente no confiaría en que nunca suceda.
Maximus Minimus
1
Vale la pena mencionar, creo que esto se relacionaría con "... si quisieras reducir el uso de la CPU ...": nanobit.net/doxy/quake3/win__main_8c-source.html <- el código relevante comienza en 01224
user_123abc
16

Respuesta corta: no, no lo es.

Para tener una velocidad de cuadro fija, debe llamar a una determinada función de devolución de llamada que fuerza una velocidad de cuadro específica. Obviamente, si no sabe cuánto tiempo durará una sola iteración en un bucle, no puede establecer un tiempo fijo para dormir.

GLUT proporciona glutTimerFunc () , que es, si está programando en OpenGL, la función correcta que necesita. Eche un vistazo a este ejemplo , o este .

Dan
fuente
1
"Después de al menos milisegundos de milisegundos, OpenGLUT llamará a la devolución de llamada": ¿en qué se diferencia eso Sleep?
Kromster dice que apoya a Monica el