Stratos: Punto de Encuentro de Desarrolladores

¡Bienvenido a Stratos!

Acceder

Foros





Micro saltos en el frame rate.

Iniciado por Pogacha, 30 de Enero de 2008, 05:49:30 AM

« anterior - próximo »

Pogacha

Hola,
Como veran estoy a full!!!

Tengo otro problema muy particular desde hace mas de un mes y no lo logro resolver.
En ciertas computadoras de escritorio y en ciertas condiciones que no puedo precisar, el juego en el cual trabajo da unos graciosos saltos en el framerate, como si hubiese una pequeña pausa cada 1/2 segundo.

No hay un patron especial sobre el tipo de computadora ni las condiciones.

El juego usa DX.
Cosas que no afectan al efecto:
* Activar o desactivar el VSync.
* Usar o no usar Sleep para liberar el tiempo muerto.
* Insultar al ordenador donde susodicho problema ocurre.

Estoy usando GetTickCount para el tema del tiempo, cosa que no puede fallar.

El game loop es basico
while(!done)
{
 dt = GetTickCount() - last_tick;
 last_tick += dt;
 if(dt>0) {
    Update(dt);
    Draw();
 } else Sleep(0);
}
Le sospechaba al Sleep pero no es eso.

La prioridad del proceso es la de por defecto, tiene un segundo thread para el audio pero este no influye para nada tampoco, con el o sin el es lo mismo.

El tema del acceso a disco para ejecutar streams puede llegar a ser un problema pero como lo hago en otro thread me parece menos posible. Podria probar a tener otro thread para hacer streaming independiente del mixer, pero me parece una exageración.

¿Que se les ocurre que pueda ser la causa de este micro-saltito?
¿Han tenido algún problema similar?
¿Como lo resolvieron? (si así fue)

Muchisimas gracias.

tamat

Sucede nada mas ejecutar la aplicacion o incluso cuando lleva rato en ejecucion?

Has mirado que no haya memory leaks? que la memoria del proceso no se incremente?

Podrias hacer profiling de la aplicacion y ver qué funcion dispara el tiempo. Medio segundo es mucho en un profiler como para no verlo.
Por un stratos menos tenso

sés

Esa función, que yo sepa, siempre ha sido un truño. Sí... te da el tiempo en milisegundos, pero con una precisión de 18.2 milisegundos.

O sea que, para esa función, sólo hay 18.2 divisiones en cada segundo. Si haces un bucle imprimiendo los valores que da, creo que dará algo como esto:

0
0
0
0
0
0
18
18
18
18
18
18
36
36
36
36
36
36
55
55
55
55
55
55
73
73
73
73
73
73
91
91
91
91
91
91
109
109
109
109
109


etc.


Como verás, si la llamas varias veces muy seguidas, te dará el mismo valor. No sirve para cosas que necesiten precisión.

Echa un ojo aquí por ejemplo: http://technology.chtsai.org/w98timer/


Que alguien me corrija si me equivoco, hace bastante que no toco este tema.
Soy indeciso... ¿o no?

Zaelsius

¿Entonces se te dispara el delta cada 1/2 segundo no?

Prueba a usar timeGetTime(), con timeBeginPeriod() al principio del programa para ajustar la resolución a 1 ms.

Otra posible solución (algo cutre pero bueno) sería usar como delta la media de los 10(p.ej.) últimos deltas, y no el delta actual.

Loover

Buenas, como han dicho, se debe a la precisión de la función que usas para obtener los milisegundos. A mi también me daba saltos (en determinados ordenadores) antes de pasarme a   QueryPerformanceCounter() y QueryPerformanceFrequency(). Después de eso fué como la seda, pues estas funcionan usan un reloj distinto, de alta precisión.

Otra opción es usar SDL_GetTicks, que internamente creo que usar las funciones que he citado antes.

http://msdn2.microsoft.com/en-us/library/ms644904.aspx
http://msdn2.microsoft.com/en-us/library/ms644905(VS.85).aspx

Aquí tienes un resume acerca de los timers y diferentes opciones: http://msdn2.microsoft.com/en-us/library/ms632592(VS.85).aspx

Citar
High-Resolution Timer

A counter is a general term used in programming to refer to an incrementing variable. Some systems include a high-resolution performance counter that provides high-resolution elapsed times.

If a high-resolution performance counter exists on the system, you can use the QueryPerformanceFrequency function to express the frequency, in counts per second. The value of the count is processor dependent. On some processors, for example, the count might be the cycle rate of the processor clock.

The QueryPerformanceCounter function retrieves the current value of the high-resolution performance counter. By calling this function at the beginning and end of a section of code, an application essentially uses the counter as a high-resolution timer. For example, suppose that QueryPerformanceFrequency indicates that the frequency of the high-resolution performance counter is 50,000 counts per second. If the application calls QueryPerformanceCounter immediately before and immediately after the section of code to be timed, the counter values might be 1500 counts and 3500 counts, respectively. These values would indicate that .04 seconds (2000 counts) elapsed while the code executed.

Un saludo.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Pogacha

Hola, muchas gracias a todos.

A la falla no la he visto nunca, tan solo me la han comentado.

Sobre queryPerformanceCounter tiene un problema conocido en las laptop donde pierde su constancia cuando el micro cambia de velocidad, por lo que no debe ser usado para juegos, al menos no sin controlar esto.

Ahora, lo de la resolusión,  puede que esté ahí el queso, que en tales ordenadores el default sea muy gordo. Voy a probar la sugerencia de Julio.

Saludos

Pogacha

Al parecer era eso, era un problema de timing.

Aca esta un link que trata el tema de timing muy completo:
http://www.geisswerks.com/ryan/FAQS/timing.html

Saludos!

Loover

Pero en el artículo concluye que lo mejor es usar QueryPerformanceCounter, ¿no es así? ¿Es lo que finalmente vas a usar? Eso que has dicho sobre los laptop no lo sabía... en los portátiles que lo he probado (solo 2) no he tenido problemas, pero claro, eso no es concluyente :P (prueba de la Looverlib).

En el juego lo que hacemos es mover las unidades mutiplicando la velocidad con lo que ha tardado el frame anterior. Con lo que no limitamos los fps de dibujo, sino los de lógica.
IndieLib Libreria 2.5d utilizando aceleración por hardware para la programación de juegos 2d.
Indie Rover The monkeys are reading!

Pogacha

QueryPerformanceTimer tiene problemas si. Pero se pueden resolver.
Creo que lo voy a tratar de usar de todos modos.

Aqui dan una descripcion de los problemas y como resolverlos.
http://www.gamedev.net/reference/articles/article2086.asp

Saludos.

Edit:
Aqui discuten el problema severamente:
http://forums.indiegamer.com/showthread.php?t=2394&page=2

Aqui incluso te dan los chips donde el error ocurre:
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q274323&;






Stratos es un servicio gratuito, cuyos costes se cubren en parte con la publicidad.
Por favor, desactiva el bloqueador de anuncios en esta web para ayudar a que siga adelante.
Muchísimas gracias.