Automatizzare i test delle prestazioni di XNA?


8

Mi chiedevo quali fossero gli approcci o i pensieri delle persone sull'automazione dei test delle prestazioni in XNA. Attualmente sto cercando di lavorare solo in 2d, ma ciò pone molte aree in cui le prestazioni possono essere migliorate con diverse implementazioni.

Un esempio potrebbe essere se tu avessi 2 diverse implementazioni di partizionamento spaziale, una potrebbe essere più veloce di un'altra ma senza fare qualche vero test delle prestazioni non saresti in grado di dire quale di sicuro (a meno che tu non abbia visto il codice era palesemente lento in alcuni parti). È possibile scrivere un test unitario che per un determinato periodo di tempo ha continuato ad aggiungere / aggiornare / rimuovere entità per entrambe le implementazioni e vedere quante ne sono state realizzate in ciascun intervallo di tempo e quello superiore sarebbe il più veloce (in questo esempio).

Un altro esempio di livello superiore sarebbe se volessi vedere quante entità puoi avere sullo schermo all'incirca senza andare sotto i 60 fps. Il problema è che per automatizzarlo dovresti usare il trucco della forma nascosta o qualche altra cosa per dare il via a un gioco simulato e testare semplicemente quali parti ti interessano e disabilitare tutto il resto.

So che questa non è una faccenda semplice, anche se puoi automatizzare i test, dipende davvero da un essere umano interpretare se i risultati sono abbastanza performanti, ma come parte di una fase di costruzione potresti farli eseguire questi test e pubblicare i risultati da qualche parte per il confronto.

In questo modo se passi dalla versione 1.1 alla 1.2 ma hai modificato alcuni algoritmi sottostanti potresti notare che in generale il punteggio delle prestazioni sarebbe aumentato, il che significa che hai migliorato le prestazioni complessive dell'applicazione, e quindi dalla 1.2 alla 1.3 potresti notare che hai quindi ridotto un po 'le prestazioni complessive.

Qualcuno ha quindi automatizzato questo genere di cose nei propri progetti e, in caso affermativo, come si misurano i confronti delle prestazioni ad alto livello e quali framework vengono utilizzati per testare? Dato che hai scritto il tuo codice in modo che sia testabile / deridibile per la maggior parte delle parti, puoi semplicemente usare i tuoi test come meccanismo per ottenere alcuni risultati prestazionali ...

=== Modifica ===

Solo per chiarezza, sono più interessato al modo migliore di utilizzare i test automatici all'interno di XNA per tenere traccia delle tue prestazioni, non giocare a test o indovinare eseguendo manualmente il gioco su una macchina. Questo è completamente diverso dal vedere se il tuo gioco è giocabile su hardware X, si tratta più di tenere traccia del cambiamento delle prestazioni man mano che il tuo motore di gioco / quadro cambia.

Come menzionato in uno dei commenti, è possibile testare facilmente "quanti nodi posso inserire / rimuovere / aggiornare in QuadTreeA entro 2 secondi", ma è necessario esaminare fisicamente questi risultati ogni volta per vedere se è cambiato, il che potrebbe essere bene ed è ancora meglio che fare affidamento sul giocare per vedere se noti qualche differenza tra la versione. Tuttavia, se dovessi inserire un Assert per avvisarti di un errore se scende al di sotto di quanto diciamo 5000 in 2 secondi hai un test fragile poiché è quindi contestuale all'hardware, non solo all'implementazione. Detto questo, questo tipo di test automatizzati è davvero utile solo se si eseguono i test come una sorta di pipeline di build, ovvero:

Acquista -> Esegui test unità -> Esegui test di integrazione -> Esegui test delle prestazioni -> Pacchetto

Quindi puoi facilmente confrontare le statistiche da una build all'altra sul server CI come un rapporto di qualche tipo, e di nuovo questo potrebbe non significare molto per nessuno se non sei abituato all'integrazione continua. Il nocciolo principale di questa domanda è vedere come le persone gestiscono questo tra build e come trovano meglio riferire. Come ho detto, può essere soggettivo, ma poiché la conoscenza verrà acquisita dalle risposte, sembra una domanda utile.


+1 ottima domanda. Non l'ho ancora fatto, ma presto devo farlo.
ashes999,

Solo per chiarire che non sto davvero parlando di profiler o strumenti esterni, anche se potrebbe essere una cosa aggiuntiva per diagnosticare sezioni lente ecc. Quello che sto pensando è di più sull'utilizzo dei test unitari per darti un contesto se stai anche migliorando le prestazioni, in modo da poter implementare un nuovo algoritmo per l'individuazione del percorso e testarlo immediatamente in isolamento rispetto alla versione precedente e confrontare immediatamente i numeri che ti dicono che l'hai migliorata o hai perso tempo senza nemmeno doverlo integrare nel progetto principale e distribuirlo.
Grofit,

la tua domanda sembra un po 'confusa; stai parlando della misurazione generale delle prestazioni, che può essere eseguita SENZA test; ma puoi anche scrivere test come "il test X avviene in meno di 3 secondi".
ashes999,

Sì, e "il test X avviene in meno di 3 secondi" è lungo il percorso giusto, ma invece un test del tipo "Quanti nodi posso inserire in un albero quad in 5 secondi", il risultato potrebbe essere per una build 10000 e la build successiva potrebbe essere 5000. Vedendo che immediatamente puoi prendere una decisione informata se hai introdotto un problema. Il problema per me è che tutte queste informazioni sono buone, ma devi andare a guardarle. Poiché l'aggiunta di un'asserzione per <7500 nel tempo può sembrare soddisfacente, ma se la si esegue su una macchina diversa potrebbe non passare, ma in realtà l'ATTUAZIONE non è più lenta.
Grofit,

Risposte:


2

Suppongo che tu voglia escludere "Esegui il gioco reale", quindi in sostanza la mia risposta è squalificata dall'inizio. Ma forse puoi toglierti qualcosa , quindi perché lo pubblico indipendentemente da:

Per la tesi del mio Master, ho varie implementazioni indipendenti / parallele per ottenere la stessa cosa per alcuni moduli del mio motore di gioco e ho bisogno di eseguire alcune misurazioni delle prestazioni. Tecnicamente, nulla mi impedirebbe di avviare il gioco e guardare i numeri visualizzati nel profiler sullo schermo, ma volevo ancora automatizzarlo perché è un processo noioso da eseguire ogni volta che la mia implementazione cambia.

Quindi quello che ho è questo:

  • Un profiler con ambito (che mette un oggetto in pila, prende un timestamp in fase di costruzione e uno in fase di decostruzione) che viene utilizzato per misurare il tempo impiegato dalla funzione / ambito di interesse per eseguire
  • Un modulo che memorizza un certo numero di campioni profilati e scarica la media negli ultimi n campioni in un semplice file di testo
  • Una riga di comando in-game che può essere utilizzata per avviare una partita, caricare una mappa, modificare l'algoritmo utilizzato all'interno del modulo da ispezionare, cambiare il percorso del file di dump del profiler e molte altre cose. Tale riga di comando è impostata per controllare un determinato file speciale all'interno della directory eseguibile e caricarlo per eseguire la stringa recuperata da esso (come mezzo di comunicazione tra processi molto, molto grezza)

Quindi ciò che mi permette di fare è avviare la mia applicazione da qualsiasi ambiente di scripting decente (per esempio, prompt dei comandi di Windows tramite script batch - ma in realtà uso Ruby a tale scopo), impostare un percorso di file di dump, caricare una mappa, lasciarlo in esecuzione per alcuni minuti, esci dal gioco in corso, imposta un altro percorso del file di dump, cambia l'algoritmo da utilizzare, carica di nuovo la mappa, risciacqua, ripeti. Lo script Ruby comunica con il gioco durante il volo creando quel file speciale che il modulo della riga di comando sta cercando e inserendo i comandi desiderati nella sintassi che la riga di comando comprende in esso.

In realtà non ho usato l'integrazione continua su questo progetto in questo momento, ma nulla mi impedirebbe di rovinare lo script Ruby per analizzare anche i registri delle prestazioni generati e produrre XML compatibile xUnit per comunicare con il sistema CI quando le prestazioni si sono inaspettatamente andato in tilt per qualche motivo ed esegui lo script su ogni build completa sul server di build.

Va bene, quindi nemmeno il mio gioco è scritto in XNA (è semplice C ++ e DirectX), né questo approccio rispetta il fatto che in realtà non si desidera eseguire il gioco sul proprio build build. Inoltre, non è per nulla flessibile come quello che probabilmente stai cercando, ma è comunque un approccio pulito e di bassa tecnologia alla misurazione automatizzata delle prestazioni che è in qualche modo compatibile con la CI (a condizione che uno abbia un server build robusto).

Modifica: quanto a quanto ho effettivamente adottato questo approccio - confronto solo le misurazioni delle prestazioni ottenute da diverse implementazioni di questo solo modulo. Ma l'intero sistema è impostato in un modo che mi consentirebbe di scaricare una delle singole categorie definite per il mio framework di profilatura leggera e utilizzare l'ambiente di scripting esterno per interpretare i risultati in qualunque modo sembri utile lì e poi. Togliendo dall'equazione l'aspetto della performance profiling, ho intenzione di farlo

  • Verifica la validità / coerenza di tutte le risorse caricando tutte le mappe contenenti tutti i modelli / trame / suoni e controllando i log del motore per qualcosa di insolito
  • sottoporre a stress il motore e monitorare i registri per eventuali comportamenti imprevisti in un arco di tempo di diverse ore / giorni

1
Tutte le informazioni utili ti hanno dato un +1. Dai suoni di ciò, anche se tutto ciò che stai facendo sopra potrebbe essere facilmente eseguito in una sorta di test di integrazione. L'unica cosa di cui devi preoccuparti è prendere in giro il gioco / simulazione reale. Dato che sei pronto a isolare i componenti dei tuoi motori / framework in modo che possano essere testati nel loro contesto, è qui che sto cercando di arrivare. Poiché non voglio testare le prestazioni del mio gioco in quanto è una bestia in continua evoluzione, il framework tuttavia cambia di rado e può essere facilmente impostato per eseguire una determinata quantità di scenari come menzionato.
Grofit

Grazie. Come sottolineato dalle cose che voglio ottenere in futuro, ho mirato ad automatizzare le cose che accadono nel gioco reale - Il risultato è stato abbastanza conveniente anche per le misurazioni delle prestazioni.
Koarl

0

Non vedo quello che descrivi come uno strumento utile. Come sviluppatore un semplice numero di prestazioni è quasi inutile.

Quello che vuoi è profilare il tuo codice, dividerlo in blocchi logici di e misurare il tempo che ciascuno di essi usa, picco e medio. Ora puoi dire quale parte del codice sta causando problemi e sai dove cercare le ottimizzazioni.

La parte difficile non è il cambiamento delle prestazioni da una build all'altra, non è necessario un automatizzato per capirlo. La parte difficile sono le differenze di prestazioni tra macchine diverse, non c'è modo di estrapolare le prestazioni da una macchina all'altra con una diversa scheda video ecc.

Quindi quello che vuoi è una funzione di benchmark in modo da poter eseguire una corsa con un clic e ottenere i numeri di profilatura. In questo modo sarai in grado di testare più macchine contemporaneamente. Esistono diversi modi per farlo, ad esempio è possibile ignorare l'input dell'utente per avvicinarsi il più possibile all'esecuzione di una normale sessione di gioco.

Potresti anche voler fare un test più lungo per individuare perdite di memoria.


3
Se segui un tipico approccio in stile CI, in cui esegui il tuo software attraverso un server di build, eseguirai sempre i test sulla stessa macchina, quindi sempre sullo stesso hardware, che ti fornisce una base per le tue figure. Dato che quella era la direzione da cui provenivo davvero. Dici che non hai bisogno di uno strumento per capire i cambiamenti delle prestazioni tra build, il che è vero che puoi eseguirlo da solo e vedere la differenza, ma sarebbe bello se il tuo sistema di build o il tuo computer attuale potesse darti quei numeri senza che tu abbia fare altro che eseguire un test.
Grofit,

Se sei almeno un po 'serio sul test, hai bisogno di più macchine di prova diverse. In ogni caso, qual è il problema reale? Non sei sicuro di come codificare un benchmark nel gioco?
aaaaaaaaaaaa,

Non vi è alcun problema in quanto tale, sto solo cercando di ottenere alcune informazioni su come alcune persone hanno applicato questo ai loro progetti. Non penso che avere macchine separate aiuti in alcun modo, poiché non stai davvero testando per vedere se funziona a 30 fps su hardware basso e 60 fps su hardware veloce. Stai togliendo l'hardware dall'equazione e stai PURAMENTE guardando il tuo motore / codice sorgente. Come in realtà non dovrebbe importare se stai testando su un 486 o un quad core, poiché stai testando una build contro un'altra, non un set di hardware ancora un altro.
Grofit,

3
Devo concordare un po 'con Grofit e eBusiness su questo. I test automatizzati sono importanti, soprattutto su progetti di grandi dimensioni, in modo che quando si verifica una build saprà se qualcosa ha danneggiato o aiutato le prestazioni, e questo è idealmente fatto su una macchina. Con almeno i giochi per PC, devi anche testare un'ampia varietà di hardware, i tuoi test automatici potrebbero dire che le prestazioni sono eccezionali, ma poi esegui il tuo gioco su una vecchia GPU o ti ritrovi a correre nella memoria virtuale e all'improvviso ai tuoi carri armati. Devi essere in grado di testare queste cose prima che raggiungano le mani dei clienti.
Nic Foster,

@Grofit Il fatto è che potrebbe essere solo la vecchia macchina che rompe la build. Non è insolito che una modifica non abbia un effetto significativo sulle prestazioni su un nuovo computer o sia addirittura un miglioramento, mentre la stessa modifica impedisce completamente l'esecuzione del gioco su un vecchio computer. Non è possibile rimuovere l'hardware dall'equazione, non esistono prestazioni di codice isolate. Ma se vuoi impostare un test automatico eseguito su una sola macchina, almeno fallo sul vecchio Junker, questo ti darà una possibilità molto migliore di fallire il test.
aaaaaaaaaaaa,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.