Automatiser les tests de performances XNA?


8

Je me demandais quelles étaient les approches ou les opinions des gens sur l'automatisation des tests de performances dans XNA. Actuellement, je ne travaille que dans 2d, mais cela pose de nombreux domaines où les performances peuvent être améliorées avec différentes implémentations.

Un exemple serait si vous aviez 2 implémentations différentes de partitionnement spatial, l'une peut être plus rapide que l'autre mais sans faire de test de performance réel, vous ne pourriez pas dire laquelle avec certitude (sauf si vous avez vu que le code était manifestement lent dans certains les pièces). Vous pouvez écrire un test unitaire qui, pendant un laps de temps donné, a continué à ajouter / mettre à jour / supprimer des entités pour les deux implémentations et à voir combien ont été effectuées dans chaque période et la plus élevée serait la plus rapide (dans cet exemple donné).

Un autre exemple de niveau supérieur serait si vous vouliez voir combien d'entités vous pouvez avoir à l'écran à peu près sans descendre en dessous de 60fps. Le problème avec cela est que pour l'automatiser, vous devrez utiliser l'astuce de forme cachée ou une autre chose pour lancer un jeu simulé et tester uniquement les parties qui vous intéressent et désactiver tout le reste.

Je sais que ce n'est pas une affaire simple, car même si vous pouvez automatiser les tests, il appartient vraiment à un humain d'interpréter si les résultats sont suffisamment performants, mais dans le cadre d'une étape de construction, vous pouvez le faire exécuter ces tests et publier les résultats quelque part pour comparaison.

De cette façon, si vous passez de la version 1.1 à 1.2 mais que vous avez modifié quelques algorithmes sous-jacents, vous remarquerez peut-être qu'en général, le score de performance aurait augmenté, ce qui signifie que vous avez amélioré vos performances globales de l'application, puis de 1.2 à 1.3, vous remarquerez peut-être que vous avez ensuite un peu baissé les performances globales.

Est-ce que quelqu'un a automatisé ce genre de chose dans ses projets, et si oui, comment mesurez-vous vos comparaisons de performances à un niveau élevé et quels cadres utilisez-vous pour tester? En fournissant que vous avez écrit votre code afin qu'il soit testable / mockable pour la plupart des parties, vous pouvez simplement utiliser vos tests comme mécanisme pour obtenir des résultats de performance ...

=== Modifier ===

Pour plus de clarté, je suis plus intéressé par la meilleure façon d'utiliser des tests automatisés au sein de XNA pour suivre vos performances, pas de jouer à des tests ou de deviner en exécutant manuellement votre jeu sur une machine. Cela est complètement différent de voir si votre jeu est jouable sur du matériel X, il s'agit davantage de suivre le changement de performances à mesure que votre moteur de jeu / framework change.

Comme mentionné dans l'un des commentaires, vous pouvez facilement tester "combien de nœuds puis-je insérer / supprimer / mettre à jour dans QuadTreeA en 2 secondes", mais vous devez regarder physiquement ces résultats à chaque fois pour voir s'il a changé, ce qui peut être très bien et c'est toujours mieux que de simplement compter sur le jouer pour voir si vous remarquez une différence entre les versions. Cependant, si vous deviez mettre un Assert pour vous informer d'un échec s'il est inférieur à 5000 disons en 2 secondes, vous avez un test fragile car il est alors contextuel au matériel, pas seulement à l'implémentation. Bien que cela étant dit, ce type de tests automatisés n'est vraiment utile que si vous exécutez vos tests comme une sorte de pipeline de construction, c'est-à-dire:

Paiement -> Exécuter les tests unitaires -> Exécuter les tests d'intégration -> Exécuter les tests de performances -> Package

Ainsi, vous pouvez facilement comparer les statistiques d'une génération à une autre sur le serveur CI sous la forme d'un rapport quelconque, et encore une fois, cela peut ne pas signifier grand-chose pour personne si vous n'êtes pas habitué à l'intégration continue. Le nœud principal de cette question est de voir comment les gens gèrent cela entre les builds et comment ils trouvent le meilleur rapport. Comme je l'ai dit, cela peut être subjectif, mais comme les connaissances seront acquises à partir des réponses, cela semble une question valable.


+1 grande question. Je ne l'ai pas encore fait, mais je dois le faire bientôt.
ashes999

Juste pour clarifier, je ne parle pas vraiment de profileurs ou d'outils externes, bien que cela puisse être une chose supplémentaire pour aider à diagnostiquer les sections lentes, etc. Je pense plus à utiliser vos tests unitaires pour vous donner un contexte pour savoir si vous améliorez également les performances, vous pouvez donc implémenter un nouvel algorithme de recherche de chemin et le tester immédiatement de manière isolée par rapport à votre version précédente, et comparer instantanément les chiffres vous indiquant que vous l'avez amélioré ou perdu votre temps sans même avoir à l'intégrer dans le projet principal et le déployer.
Grofit

votre question semble un peu confuse; vous parlez de mesure générale des performances, qui peut être effectuée SANS tests; mais vous pouvez également écrire des tests comme "le test X se produit en moins de 3 secondes".
ashes999

Oui et que "le test X se produit en moins de 3 secondes" est sur le bon chemin, mais à la place d'un test comme "combien de nœuds puis-je insérer dans un arbre quad en 5 secondes", le résultat de cela pour une construction peut être 10000, et la prochaine génération peut être 5000. En voyant cela immédiatement, vous pouvez prendre une décision éclairée si vous avez introduit un problème. Le problème pour moi est que toutes ces informations sont bonnes, mais vous devez aller les consulter. Comme l'ajout d'une assertion pour <7500 dans le temps peut sembler correct, mais si vous l'exécutez sur une machine différente, cela peut ne pas réussir, mais en réalité la MISE EN ŒUVRE n'est pas plus lente.
Grofit

Réponses:


2

Je suppose que vous voulez complètement exclure "Exécuter le jeu réel", donc fondamentalement ma réponse est disqualifiée dès le départ. Mais peut-être que vous pouvez en retirer quelque chose , d'où la raison pour laquelle je poste ceci:

Pour ma thèse de maîtrise, j'ai plusieurs implémentations indépendantes / parallèles pour réaliser la même chose pour certains modules de mon moteur de jeu et j'ai besoin de réaliser quelques mesures de performances. Techniquement, rien ne m'empêcherait de simplement lancer le jeu et de regarder les chiffres affichés dans le profileur à l'écran, mais je voulais toujours automatiser cela parce que c'est un processus fastidieux à effectuer chaque fois que mon implémentation change.

Donc, ce que j'ai, c'est ceci:

  • Un profileur de portée (qui place un objet sur la pile, prend un horodatage lors de la construction et un lors de la déconstruction) qui est utilisé pour mesurer le temps nécessaire à l'exécution de la fonction / étendue d'intérêt.
  • Un module qui stocke un certain nombre d'échantillons profilés et transfère la moyenne des n derniers échantillons dans un fichier texte simple
  • Une ligne de commande dans le jeu qui peut être utilisée pour démarrer un jeu, charger une carte, changer l'algorithme utilisé dans le module à inspecter, changer le chemin du fichier de vidage du profileur et beaucoup d'autres choses. Ladite ligne de commande est configurée pour vérifier un certain fichier spécial dans le répertoire exécutable et le charger pour exécuter la chaîne récupérée à partir de lui (comme moyen de communication inter-processus très, très grossière)

Donc, cela me permet de lancer mon application à partir de n'importe quel environnement de script à moitié décent (par exemple, l'invite de commande Windows via des scripts batch - mais j'utilise en fait Ruby à cette fin), définir un chemin de fichier de vidage, charger une carte, le laisser en cours d'exécution pendant quelques minutes, quittez le jeu en cours d'exécution, définissez un autre chemin de fichier de vidage, changez l'algorithme à utiliser, chargez à nouveau la carte, rincez, répétez. Le script Ruby communique avec le jeu en vol en créant ce fichier spécial que le module de ligne de commande recherche et en mettant les commandes souhaitées dans la syntaxe que la ligne de commande comprend.

Je n'ai pas réellement utilisé l'intégration continue sur ce projet pour le moment, mais rien ne m'empêcherait de gonfler ce script Ruby pour analyser également les journaux de performances générés et produire du XML compatible xUnit pour communiquer avec le système CI lorsque les performances se sont inopinément allé détraqué pour une raison quelconque et exécuter le script sur chaque build complet sur le serveur de build.

D'accord, donc mon jeu n'est pas écrit en XNA (c'est du C ++ et DirectX), et cette approche ne respecte pas le fait que vous ne voulez pas réellement exécuter le jeu sur votre serveur de build. Il est également loin d'être aussi flexible que ce que vous recherchez probablement - mais tout de même, c'est une approche soignée et à faible technologie pour la mesure automatisée des performances qui est quelque peu compatible avec les CI (à condition que l'on ait un serveur de construction costaud).

Edit: Quant à savoir jusqu'où j'ai réellement pris cette approche - je ne compare que les mesures de performances obtenues à partir de différentes implémentations de ce seul module. Mais l'ensemble du système est configuré de manière à me permettre de vider n'importe laquelle des catégories définies pour mon cadre de profilage léger et d'utiliser l'environnement de script externe pour interpréter les résultats de la manière qui semble utile immédiatement. En retirant l'aspect profilage des performances de l'équation, j'ai également l'intention de

  • Vérifiez la validité / cohérence de tous les actifs en chargeant toutes les cartes contenant tous les modèles / textures / sons et en vérifiant les journaux du moteur pour tout ce qui est inhabituel
  • tester le moteur et surveiller les journaux pour tout comportement inattendu de cette façon sur une période de plusieurs heures / jours

1
Toutes les bonnes informations vous ont donné un +1. D'après les sons, tout ce que vous faites ci-dessus pourrait facilement être fait dans un test d'intégration. La seule chose dont vous devez vous soucier est de vous moquer du jeu / de la simulation. Comme vous êtes sur le point de rendre vos composants moteurs / frameworks isolés afin qu'ils puissent être testés dans leur propre contexte, c'est là que j'essaie d'arriver. Comme je ne veux pas tester les performances de mon jeu car c'est une bête en constante évolution, le cadre change cependant rarement et peut facilement être configuré pour exécuter une quantité donnée de scénarios comme vous le mentionnez.
Grofit

Merci. Comme souligné par les choses que je veux réaliser à l'avenir, je visais à automatiser des choses qui se passent dans le vrai jeu - Le résultat s'est avéré tout aussi pratique pour les mesures de performances.
Koarl

0

Je ne vois pas ce que vous décrivez comme un outil utile. En tant que développeur, un simple indice de performance est presque inutile.

Ce que vous voulez est de profiler votre code, de le diviser en morceaux logiques et de mesurer combien de temps chacun utilise, pointe et moyenne. Vous pouvez maintenant savoir quelle partie du code cause des problèmes et vous savez où chercher les optimisations.

La partie délicate n'est pas les changements de performances d'une génération à l'autre, vous n'avez pas besoin d'un automatisé pour le comprendre. La partie délicate est les différences de performances entre les différentes machines, il n'y a aucun moyen d'extrapoler les performances d'une machine à une autre avec une carte vidéo différente, etc.

Donc, ce que vous voulez, c'est une fonctionnalité de référence afin que vous puissiez faire une course en un clic et obtenir les numéros de profilage. De cette façon, vous pourrez tester plusieurs machines simultanément. Il existe plusieurs façons de le faire, par exemple, vous pouvez remplacer l'entrée utilisateur pour vous rapprocher le plus possible de l'exécution d'une session de jeu normale.

Vous pouvez également souhaiter avoir un test plus long afin de détecter les fuites de mémoire.


3
Si vous suivez une approche de style CI typique, où vous exécutez votre logiciel via un serveur de build, vous testerez toujours sur la même machine, donc toujours le même matériel, ce qui vous donne une base de référence pour vos chiffres. Comme c'était la direction d'où je venais vraiment. Vous dites que vous n'avez pas besoin d'un outil pour comprendre les changements de performances entre les générations, ce qui est vrai, vous pouvez l'exécuter vous-même et voir la différence, mais ce serait formidable si votre système de génération ou votre ordinateur actuel pouvait vous donner ces chiffres sans que vous ayez pour faire autre chose que d'exécuter un test.
Grofit

Si vous êtes le moins sérieux au sujet des tests, vous avez besoin de plusieurs machines de test différentes. Dans tous les cas, quel est le vrai problème? Vous ne savez pas comment coder une référence dans le jeu?
aaaaaaaaaaaa

Il n'y a pas de problème en tant que tel, j'essaie simplement d'obtenir des informations sur la façon dont certaines personnes ont appliqué cela à leurs projets. Je ne pense pas que le fait d'avoir des machines séparées aide en aucune façon, car vous ne testez pas vraiment pour voir s'il fonctionne à 30 images par seconde sur du matériel faible et à 60 images par seconde sur du matériel rapide. Vous retirez le matériel de l'équation et regardez PUREMENT votre moteur / code source. En fait, cela ne devrait pas avoir d'importance si vous testez sur un 486 ou un quad core, car vous testez une version contre une autre, pas un ensemble de matériel à nouveau.
Grofit

3
Je dois être un peu d'accord avec Grofit et eBusiness sur celui-ci. Les tests automatisés sont importants, en particulier sur les grands projets, de sorte que lorsque n'importe quelle construction passe, vous saurez si quelque chose a nui ou amélioré les performances, et cela est idéalement fait sur une seule machine. Avec les jeux PC au moins, vous devez également tester de nombreuses variétés de matériel, vos tests automatisés peuvent dire que les performances sont excellentes, mais vous exécutez votre jeu sur un ancien GPU ou vous vous retrouvez en train de courir dans la mémoire virtuelle et tout à coup, vos performances. Vous devez être en mesure de tester ces éléments avant qu'ils n'atteignent les mains des clients.
Nic Foster

@Grofit Le truc, c'est que c'est peut-être juste l'ancienne machine qui rompt la construction. Il n'est pas inhabituel qu'un changement n'ait pas d'effet significatif sur les performances d'un nouvel ordinateur, ni même une amélioration, tandis que le même changement empêche complètement le jeu de fonctionner sur un ancien ordinateur. Vous ne pouvez pas retirer le matériel de l'équation, les performances de code isolé n'existent pas. Mais si vous souhaitez configurer un test automatisé sur une seule machine, faites-le au moins sur l'ancien junker, cela vous donnera une meilleure chance d'échouer.
aaaaaaaaaaaa
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.