¿Automatizar las pruebas de rendimiento de XNA?

8

Me preguntaba qué enfoques o ideas tenían las personas sobre la automatización de las pruebas de rendimiento en XNA. Actualmente solo estoy buscando trabajar en 2d, pero eso plantea muchas áreas donde el rendimiento puede mejorarse con diferentes implementaciones.

Un ejemplo sería si tuviera 2 implementaciones diferentes de particionamiento espacial, una puede ser más rápida que otra, pero sin hacer algunas pruebas de rendimiento reales, no podría saber cuál es seguro (a menos que haya visto que el código era descaradamente lento en ciertos casos). partes). Podría escribir una prueba unitaria que, durante un período de tiempo determinado, siguiera agregando / actualizando / eliminando entidades para ambas implementaciones y ver cuántas se hicieron en cada período de tiempo y la más alta sería la más rápida (en este ejemplo dado).

Otro ejemplo de nivel superior sería si quisiera ver cuántas entidades puede tener en la pantalla aproximadamente sin pasar de 60 fps. El problema con esto es automatizarlo, necesitaría usar el truco de forma oculta o alguna otra cosa para comenzar un juego simulado y probar puramente qué partes le importan y desactivar todo lo demás.

Sé que esto no es un asunto simple, ya que incluso si puede automatizar las pruebas, realmente depende de un humano interpretar si los resultados son lo suficientemente efectivos, pero como parte de un paso de compilación, puede hacer que ejecute estas pruebas y publique Los resultados en algún lugar para la comparación.

De esta manera, si pasa de la versión 1.1 a la 1.2 pero ha cambiado algunos algoritmos subyacentes, puede notar que, en general, la puntuación de rendimiento habría aumentado, lo que significa que ha mejorado el rendimiento general de la aplicación, y luego de 1.2 a 1.3 puede notar que luego bajó un poco el rendimiento general

Entonces, ¿alguien ha automatizado este tipo de cosas en sus proyectos, y si es así, cómo mide sus comparaciones de rendimiento a un alto nivel y qué marcos utiliza para probar? Como siempre que haya escrito su código para que sea comprobable / imitable para la mayoría de las partes, puede usar sus pruebas como un mecanismo para obtener algunos resultados de rendimiento ...

=== Editar ===

Solo por claridad, estoy más interesado en la mejor manera de hacer uso de pruebas automatizadas dentro de XNA para rastrear su rendimiento, no para probar o adivinar ejecutando manualmente su juego en una máquina. Esto es completamente diferente a ver si su juego se puede jugar en hardware X, se trata más de rastrear el cambio en el rendimiento a medida que cambia el motor / marco del juego.

Como se menciona en uno de los comentarios, podría probar fácilmente "cuántos nodos puedo insertar / eliminar / actualizar dentro de QuadTreeA en 2 segundos", pero debe ver estos resultados físicamente cada vez para ver si ha cambiado, lo que puede ser bien y aún es mejor que solo confiar en jugarlo para ver si notas alguna diferencia entre las versiones. Sin embargo, si tuviera que colocar un Assert para notificarle de un error si es inferior a, digamos 5000 en 2 segundos, tiene una prueba frágil, ya que es contextual al hardware, no solo a la implementación. Aunque dicho esto, este tipo de pruebas automatizadas solo son realmente útiles si está ejecutando sus pruebas como algún tipo de tubería de compilación, es decir:

Pago -> Ejecutar pruebas de unidad -> Ejecutar pruebas de integración -> Ejecutar pruebas de rendimiento -> Paquete

Entonces, puede comparar fácilmente las estadísticas de una compilación a otra en el servidor CI como un informe de algún tipo, y nuevamente esto puede no significar mucho para nadie si no está acostumbrado a la Integración continua. El quid principal de esta pregunta es ver cómo las personas manejan esto entre las compilaciones y cómo les resulta mejor informar. Como dije, puede ser subjetivo, pero como el conocimiento se obtendrá de las respuestas, parece una pregunta que vale la pena.

Grofit
fuente
+1 gran pregunta. Todavía no he hecho esto, pero necesito hacerlo pronto.
cenizas999
Solo para aclarar que en realidad no estoy hablando de perfiladores o herramientas externas, aunque eso podría ser una cosa adicional para ayudar a diagnosticar secciones lentas, etc. Lo que estoy pensando es más sobre hacer uso de sus pruebas unitarias para darle algo de contexto sobre si también está mejorando el rendimiento, por lo que podría implementar un nuevo algoritmo para la búsqueda de rutas, e inmediatamente probarlo de forma aislada con su versión anterior, y comparar los números instantáneamente diciéndole que lo ha mejorado o perdido su tiempo sin siquiera tener que integrarlo en el proyecto principal y desplegarlo.
Grofit
tu pregunta parece un poco confusa; estás hablando de la medición general del rendimiento, que se puede hacer SIN pruebas; pero también puede escribir pruebas como "la prueba X ocurre en menos de 3 segundos".
cenizas999
Sí, y que "la prueba X ocurre en menos de 3 segundos" está en el camino correcto, pero en lugar de una prueba como "¿Cuántos nodos puedo insertar en un árbol cuádruple en 5 segundos", el resultado de eso para una compilación puede ser 10000, y la próxima generación puede ser 5000. Al ver eso de inmediato, puede tomar una decisión informada sobre si ha introducido un problema. El problema para mí es que toda esta información es buena, pero hay que ir a verla. Como agregar una afirmación para <7500 en el tiempo puede parecer correcto, pero si lo ejecuta en una máquina diferente, puede que no pase, pero en realidad la IMPLEMENTACIÓN no es más lenta.
Grofit

Respuestas:

2

Supongo que quieres descartar por completo "Ejecutar el juego real", así que básicamente mi respuesta está descalificada desde el principio. Pero tal vez puedas quitarle algo , por eso publico esto independientemente:

Para mi tesis de maestría, tengo varias implementaciones independientes / paralelas para lograr lo mismo para algunos módulos de mi motor de juego y necesito llevar a cabo algunas mediciones de rendimiento. Técnicamente, nada me impediría simplemente ejecutar el juego y mirar los números que se muestran en el generador de perfiles en pantalla, pero aún así quería automatizar eso porque es un proceso tedioso para realizar cada vez que cambia mi implementación.

Entonces, lo que tengo es esto:

  • Un perfilador de ámbito (que coloca un objeto en la pila, toma una marca de tiempo en la construcción y uno en la deconstrucción) que se usa para medir cuánto tiempo tardó en ejecutarse la función / alcance de interés
  • Un módulo que almacena un cierto número de muestras perfiladas y descarga la media en las últimas n muestras en un archivo de texto simple
  • Una línea de comando en el juego que se puede usar para iniciar un juego, cargar un mapa, cambiar el algoritmo que se usa dentro del módulo a inspeccionar, cambiar la ruta del archivo de volcado del generador de perfiles y muchas otras cosas. Dicha línea de comando está configurada para verificar un determinado archivo especial dentro del directorio ejecutable y cargarlo para ejecutar la cadena recuperada de él (como un medio de comunicación entre procesos muy, muy cruda)

Entonces, lo que me permite hacer es iniciar mi aplicación desde cualquier entorno de secuencias de comandos medio decente (por ejemplo, símbolo del sistema de Windows a través de secuencias de comandos por lotes, pero en realidad uso Ruby para ese propósito), establecer una ruta de archivo de volcado, cargar un mapa, dejarlo corriendo durante unos minutos, salga del juego en ejecución, configure otra ruta de archivo de volcado, cambie el algoritmo para usar, cargue el mapa nuevamente, enjuague, repita. El script Ruby se comunica con el juego en vuelo creando ese archivo especial que el módulo de línea de comando está buscando y colocando los comandos deseados en la sintaxis que la línea de comando comprende.

En realidad, no tengo una integración continua en este proyecto en este momento, pero nada me impedirá agotar ese script de Ruby para analizar también los registros de rendimiento generados y producir XML compatible con xUnit para comunicarse con el sistema CI cuando el rendimiento ha inesperadamente se ha vuelto loco por alguna razón y ejecuta el script en cada compilación completa en el servidor de compilación.

Muy bien, mi juego tampoco está escrito en XNA (es simple C ++ y DirectX), ni este enfoque respeta el hecho de que en realidad no quieres ejecutar el juego en tu servidor de compilación. Tampoco es tan flexible como lo que probablemente está buscando, pero aún así, es un enfoque ordenado y de baja tecnología para la medición automatizada del rendimiento que es algo amigable con CI (siempre que uno tenga un servidor de construcción robusto).

Editar: En cuanto a qué tan lejos he llegado a ese enfoque, solo comparo las mediciones de rendimiento obtenidas de diferentes implementaciones de solo este módulo. Pero todo el sistema está configurado de una manera que me permitiría volcar cualquiera de las categorías definidas para mi marco de creación de perfiles liviano y usar el entorno de secuencias de comandos externo para interpretar los resultados de cualquier manera que parezca útil en ese momento. Tomando el aspecto del perfil de rendimiento de la ecuación, tengo la intención de

  • Verifique la validez / consistencia de todos los activos cargando todos los mapas que contienen todos los modelos / texturas / sonidos y verificando los registros del motor por cualquier cosa inusual
  • Haga una prueba de esfuerzo del motor y monitoree los registros para detectar cualquier comportamiento inesperado de esa manera en un intervalo de tiempo de varias horas / días
Koarl
fuente
1
Toda buena información, te he dado un +1. Por lo que parece, todo lo que está haciendo arriba podría hacerse fácilmente en una especie de prueba de integración. Lo único por lo que debe preocuparse es burlarse del juego / simulación real. A medida que avanza haciendo aislar los componentes de sus motores / frameworks para que puedan probarse en su propio contexto, ahí es donde estoy tratando de llegar. Como no quiero probar el rendimiento de mi juego, ya que es una bestia en constante cambio, el marco rara vez cambia y se puede configurar fácilmente para ejecutar una cantidad determinada de escenarios como usted menciona.
Grofit
Gracias. Como lo señalaron las cosas que quiero lograr en el futuro, apunté a automatizar las cosas que suceden en el juego real: el resultado resultó ser bastante conveniente para las mediciones de rendimiento también.
Koarl
0

No veo lo que describe como una herramienta útil. Como desarrollador, un número de rendimiento simple es casi inútil.

Lo que desea es perfilar su código, dividirlo en fragmentos lógicos y medir cuánto tiempo cada uno de ellos usa, pico y promedio. Ahora puede saber qué parte del código está causando problemas, y sabe dónde buscar optimizaciones.

La parte difícil no son los cambios de rendimiento de una compilación a otra, no necesita un automatizado para darse cuenta de eso. La parte difícil es las diferencias de rendimiento entre diferentes máquinas, no hay forma de extrapolar el rendimiento de una máquina a otra con una tarjeta de video diferente, etc.

Entonces, lo que desea es una función de referencia para que pueda hacer una ejecución con un solo clic y obtener los números de perfil. De esta forma, podrá probar varias máquinas simultáneamente. Hay varias formas de hacerlo, por ejemplo, puede anular la entrada del usuario para estar lo más cerca posible de ejecutar una sesión de juego normal.

También es posible que desee realizar una prueba más larga para detectar pérdidas de memoria.

aaaaaaaaaaaa
fuente
3
Si sigue un enfoque típico de estilo CI, donde ejecuta su software a través de un servidor de compilación, siempre estará probando en la misma máquina, por lo que siempre tendrá el mismo hardware, lo que le proporciona una base para sus cifras. Como esa era la dirección de donde venía realmente. Dice que no necesita una herramienta para determinar los cambios de rendimiento entre las compilaciones, lo cual es cierto, puede ejecutarlo usted mismo y ver la diferencia, pero sería excelente si su sistema de compilación o su computadora actual pudieran darle esos números sin que tenga hacer otra cosa que no sea ejecutar una prueba.
Grofit
Si eres un poco serio acerca de las pruebas, necesitas varias máquinas de prueba diferentes. En cualquier caso, ¿cuál es el problema real? ¿No estás seguro de cómo codificar un punto de referencia en el juego?
aaaaaaaaaaaa
No hay ningún problema como tal, solo estoy tratando de obtener información sobre cómo algunas personas han aplicado esto a sus proyectos. No creo que tener máquinas separadas ayude de ninguna manera, ya que realmente no estás probando para ver si funciona a 30 fps en hardware bajo y 60 fps en hardware rápido. Está sacando el hardware de la ecuación y PURAMENTE mirando su motor / código fuente. Como realmente no debería importar si está probando en un 486 o un núcleo cuádruple, ya que está probando una compilación contra otra, no un conjunto de hardware contra otro.
Grofit
3
Tengo que estar un poco de acuerdo con Grofit y eBusiness en este caso. Las pruebas automatizadas son importantes, especialmente en proyectos grandes, de modo que cuando se realice cualquier compilación, se sabrá si algo ha dañado o ayudado al rendimiento, y esto se hace idealmente en una máquina. Con los juegos de PC, al menos, también debe probar una amplia variedad de hardware, sus pruebas automáticas pueden decir que el rendimiento es excelente, pero luego ejecuta su juego en una GPU antigua o se encuentra corriendo en la memoria virtual y de repente sus tanques de rendimiento. Debe poder probar esas cosas antes de que lleguen a las manos de los clientes.
Nic Foster
@Grofit La cuestión es que puede ser solo la vieja máquina la que rompe la compilación. No está fuera de lo normal que un cambio no tenga un efecto significativo en el rendimiento de una computadora nueva, o incluso sea una mejora, mientras que el mismo cambio evita por completo que el juego se ejecute en una computadora vieja. No puede quitar el hardware de la ecuación, no existe el rendimiento de código aislado. Pero si desea configurar una ejecución de prueba automatizada en una sola máquina, al menos hacerlo en un viejo junker, eso le dará una mejor oportunidad de que la prueba falle.
aaaaaaaaaaaa