2012-01-02 9 views
7

Tengo un programa que usa Sleep Llamada API Win32 para hacer que un hilo espere durante un período de tiempo específico.
En resumen, simula una cámara mediante el envío de imágenes captadas previamente en la memoria. Estoy usando Sleep para simular la velocidad de fotogramas - Sleep(1000/fps)Comportamiento 'Dormir' extraño entre sistemas

Esto funciona bien en mi sistema de desarrollo (Intel i5 (primera generación), Win7 64), pero cuando lo ejecuto en otro sistema (Intel i7-2600 - SandyBridge), los tiempos de sueño son totalmente diferentes e inexactos.

Por ejemplo, Sleep(16) duerme durante todo 32ms
Sleep(3) tiene capacidad para 16ms

En el pasado pensé que había un mínimo de tiempo de sueño en las ventanas de 15ms pero no consiguen que la limitación en mi sistema de desarrollo.

¿Alguna idea?

Además, ¿hay una mejor manera de lograr la velocidad de cuadro de mi simulador?

+0

¿Estás hablando de la Win32 [ 'Sleep'] (http://msdn.microsoft.com/en-us/library/windows/desktop/ms686298.aspx) función, o la función C ['sleep'] (http://pubs.opengroup.org/onlinepubs/009604599/functions/sleep.html) (tenga en cuenta la carcasa de la 's')? Su descripción hace alusión a la primera, su ortografía/nomenclatura y etiquetas (más bien genéricas) en la otra. –

+0

@ Christian.K - Win32 'Sleep' – Itsik

Respuesta

7

La función sleep garantiza que dormirá al menos la cantidad especificada en la llamada. Causa que el hilo se suspenda, permitiendo el cambio a otros hilos (regidos por las prioridades del hilo) a gusto del planificador. En otras palabras, el hilo de dormir es no garantizado para ejecutarse inmediatamente después de que haya transcurrido el tiempo especificado, por lo que debe evitarse el uso de sleep en el caso general.

Sin embargo, existen formas de lograr dormir con mayor precisión en Windows. Puede llamar al timeGetDevCaps para determinar la resolución del temporizador mínima admitida, y luego llamar al timeBeginPeriod una vez al principio de su aplicación para establecer la resolución del temporizador a su mínimo. Asegúrese de llamar al timeEndPeriod antes de que salga su aplicación.

Para obtener más información, vea the Sleep function on MSDN.

+0

He intentado ejecutar' timeBeginPeriod' pero no tiene ningún efecto sobre la duración. – Itsik

+0

¿Estás seguro de que fue exitoso, es decir, devuelto 'TIMERR_NOERROR' [como se describe en MSDN] (http://msdn.microsoft.com/en-us/library/windows/desktop/dd757624 (v = vs.85) .aspx)? –

1

En lugar de confiar en el comportamiento de sueño impreciso o las funciones de temporizador específicas de la plataforma (que pueden funcionar bien, no sé), podría estructurar esto como un bucle de juego.

Dentro del bucle se llama a una función para darle la hora actual. Calcula cuánto tiempo ha transcurrido desde que dibujó el último fotograma y decide cuándo renderizar el siguiente fotograma exactamente en el momento correcto. Durante el desarrollo, debe medir la cantidad real de cuadros por segundo y mostrarlos.

Con este enfoque, es más fácil hacer su código multiplataforma y más preciso. También su bucle está en control en lugar de estructurar su código como devoluciones de llamada del temporizador que también podría preferir.

La desventaja es que un bucle de "espera ocupada" significa que su proceso utilizará la CPU todo el tiempo innecesariamente. Para mitigar eso, puede ceder la CPU en su ciclo al bombear explícitamente los eventos de la interfaz de usuario de alguna manera o tal vez utilizando un modo de espera más corto :-).

Si desea obtener más información acerca de este enfoque, comience a buscar material en los bucles de los juegos.

Éstos son algunos enlaces esenciales:

http://www.koonsolo.com/news/dewitters-gameloop/

http://gafferongames.com/game-physics/fix-your-timestep/

y una discusión sobre SO:

https://gamedev.stackexchange.com/questions/1589/fixed-time-step-vs-variable-time-step