XNA-Leistungstests automatisieren?

8

Ich habe mich gefragt, welche Ansätze oder Gedanken die Leute zur Automatisierung von Leistungstests in XNA hatten. Momentan möchte ich nur in 2d arbeiten, aber das wirft viele Bereiche auf, in denen die Leistung mit verschiedenen Implementierungen verbessert werden kann.

Ein Beispiel wäre, wenn Sie zwei verschiedene Implementierungen der räumlichen Partitionierung hätten, eine wäre möglicherweise schneller als die andere, aber ohne einige tatsächliche Leistungstests könnten Sie nicht sicher sagen, welche (es sei denn, Sie haben gesehen, dass der Code in bestimmten Fällen offensichtlich langsam ist Teile). Sie könnten einen Komponententest schreiben, der für einen bestimmten Zeitraum immer wieder Entitäten für beide Implementierungen hinzufügt / aktualisiert / entfernt und sieht, wie viele in jedem Zeitrahmen erstellt wurden und der höhere der schnellere ist (in diesem Beispiel).

Ein weiteres Beispiel auf höherer Ebene wäre, wenn Sie sehen möchten, wie viele Entitäten Sie ungefähr auf dem Bildschirm haben können, ohne unter 60 fps zu fallen. Das Problem dabei ist , es automatisieren zu können, muss die versteckte Form Trick oder eine andere Sache verwenden , um ein Kick - off Mock Spiel und rein Test , welche Teilen Sie und deaktivieren Sie alles anderes kümmern.

Ich weiß, dass dies keine einfache Angelegenheit ist, denn selbst wenn Sie die Tests automatisieren können, liegt es an einem Menschen, zu interpretieren, ob die Ergebnisse leistungsfähig genug sind, aber als Teil eines Build-Schritts könnten Sie diese Tests ausführen und veröffentlichen lassen die Ergebnisse irgendwo zum Vergleich.

Auf diese Weise stellen Sie möglicherweise fest, dass der Leistungsfaktor im Allgemeinen gestiegen ist, wenn Sie von Version 1.1 auf 1.2 wechseln, aber einige zugrunde liegende Algorithmen geändert haben, was bedeutet, dass Sie die Gesamtleistung der Anwendung verbessert haben, und dann von 1.2 auf 1.3 dass Sie dann die Gesamtleistung etwas gesenkt haben.

Hat jemand so etwas in seinen Projekten automatisiert, und wenn ja, wie messen Sie Ihre Leistungsvergleiche auf hohem Niveau und welche Frameworks verwenden Sie zum Testen? Vorausgesetzt, Sie haben Ihren Code so geschrieben, dass er für die meisten Teile testbar / verspottbar ist, können Sie Ihre Tests einfach als Mechanismus verwenden, um einige Leistungsergebnisse zu erhalten ...

=== Bearbeiten ===

Aus Gründen der Klarheit bin ich mehr daran interessiert, wie Sie automatisierte Tests in XNA am besten nutzen können, um Ihre Leistung zu verfolgen, und nicht, um Tests oder Vermutungen durchzuführen, indem Sie Ihr Spiel manuell auf einem Computer ausführen. Dies unterscheidet sich grundlegend davon, ob Ihr Spiel auf X-Hardware spielbar ist. Es geht vielmehr darum, die Leistungsänderung zu verfolgen, wenn sich Ihre Spiel-Engine / Ihr Framework ändert.

Wie in einem der Kommentare erwähnt, können Sie leicht testen, "wie viele Knoten ich innerhalb von 2 Sekunden in QuadTreeA einfügen / entfernen / aktualisieren kann", aber Sie müssen diese Ergebnisse jedes Mal physisch überprüfen, um festzustellen, ob sie sich geändert haben gut und ist immer noch besser, als sich nur darauf zu verlassen, es zu spielen, um zu sehen, ob Sie einen Unterschied zwischen den Versionen bemerken. Wenn Sie jedoch einen Assert eingeben, um Sie über einen Fehler zu informieren, wenn dieser niedriger als beispielsweise 5000 in 2 Sekunden ist, haben Sie einen spröden Test, da dieser dann kontextabhängig zur Hardware und nicht nur zur Implementierung ist. Obwohl diese Art von automatisierten Tests nur dann wirklich von Nutzen ist, wenn Sie Ihre Tests als eine Art Build-Pipeline ausführen, dh:

Kasse -> Unit-Tests ausführen -> Integrationstests ausführen -> Leistungstests ausführen -> Paket

Auf diese Weise können Sie die Statistiken von einem Build zum anderen auf dem CI-Server leicht als Bericht vergleichen. Auch dies bedeutet für niemanden viel, wenn Sie nicht an Continuous Integration gewöhnt sind. Der Hauptschwerpunkt dieser Frage ist, wie die Leute dies zwischen den Builds verwalten und wie sie es am besten finden, darüber zu berichten. Wie gesagt, es kann subjektiv sein, aber da aus den Antworten Wissen gewonnen wird, scheint es eine lohnende Frage zu sein.

Grofit
quelle
+1 tolle Frage. Ich habe das noch nicht getan, muss es aber bald tun.
Asche999
Um dies zu verdeutlichen, spreche ich nicht wirklich über Profiler oder externe Tools, obwohl dies eine zusätzliche Hilfe bei der Diagnose langsamer Abschnitte usw. sein könnte. Ich denke eher, dass Sie Ihre Komponententests verwenden, um Ihnen einen Kontext zu geben, ob Sie verbessern auch die Leistung, sodass Sie einen neuen Algorithmus für die Pfadfindung implementieren und ihn sofort isoliert mit Ihrer vorherigen Version testen und die Zahlen vergleichen können, die Ihnen sofort mitteilen, dass Sie ihn verbessert oder Ihre Zeit verschwendet haben, ohne ihn überhaupt integrieren zu müssen in das Hauptprojekt und stellen Sie es bereit.
Grofit
Ihre Frage scheint etwas verwirrt zu sein. Sie sprechen von einer allgemeinen Leistungsmessung, die OHNE Tests durchgeführt werden kann. Sie können aber auch Tests wie "Test X dauert weniger als 3 Sekunden" schreiben.
Asche999
Ja, und "Test X findet in weniger als 3 Sekunden statt" befindet sich auf dem richtigen Weg, aber anstelle eines Tests wie "Wie viele Knoten kann ich in 5 Sekunden in einen Quad-Baum einfügen" kann das Ergebnis für einen Build sein 10000, und der nächste Build kann 5000 sein. Wenn Sie dies sehen, können Sie sofort eine fundierte Entscheidung treffen, ob Sie ein Problem eingeführt haben. Das Problem für mich ist, dass all diese Informationen gut sind, aber Sie müssen sie sich ansehen. Das Hinzufügen einer Zusicherung für <7500 in der Zeit mag in Ordnung erscheinen, aber wenn Sie sie auf einem anderen Computer ausführen, wird sie möglicherweise nicht bestanden, aber in Wirklichkeit ist die UMSETZUNG nicht langsamer.
Grofit

Antworten:

2

Ich nehme an, Sie möchten "Run the actual game" komplett ausschließen, daher wird meine Antwort von Anfang an disqualifiziert. Aber vielleicht kannst du etwas davon wegnehmen, deshalb poste ich das trotzdem:

Für meine Masterarbeit habe ich verschiedene unabhängige / parallele Implementierungen, um dasselbe für einige Module meiner Game Engine zu erreichen, und ich muss einige Leistungsmessungen durchführen. Technisch gesehen würde mich nichts daran hindern, nur das Spiel auszuführen und die im Bildschirmprofiler angezeigten Zahlen zu betrachten, aber ich wollte das trotzdem automatisieren, da es ein mühsamer Prozess ist, wenn sich meine Implementierung ändert.

Was ich also habe, ist Folgendes:

  • Ein Profiler mit Gültigkeitsbereich (der ein Objekt auf den Stapel legt, einen Zeitstempel für die Konstruktion und einen für die Dekonstruktion benötigt), mit dem gemessen wird, wie lange die Ausführung der Funktion / des interessierenden Bereichs gedauert hat
  • Ein Modul, das eine bestimmte Anzahl von Profilproben speichert und den Mittelwert über die letzten n Proben in eine einfache Textdatei speichert
  • Eine In-Game-Befehlszeile, mit der Sie ein Spiel starten, eine Karte laden, den Algorithmus ändern können, der in dem zu prüfenden Modul verwendet wird, den Pfad der Profiler-Dump-Datei ändern und viele andere Dinge. Diese Befehlszeile ist so eingerichtet, dass im ausführbaren Verzeichnis nach einer bestimmten speziellen Datei gesucht und diese geladen wird, um die daraus abgerufene Zeichenfolge auszuführen (als Mittel für eine sehr, sehr grobe Kommunikation zwischen Prozessen).

Auf diese Weise kann ich meine Anwendung von einer halbwegs anständigen Skriptumgebung aus starten (z. B. Windows-Eingabeaufforderung über Batch-Skripte - aber ich verwende Ruby tatsächlich für diesen Zweck), einen Speicherauszugsdateipfad festlegen, eine Karte laden und verlassen Laufen Sie für ein paar Minuten, beenden Sie das laufende Spiel, legen Sie einen anderen Dump-Dateipfad fest, wechseln Sie den zu verwendenden Algorithmus, laden Sie die Karte erneut, spülen Sie sie aus und wiederholen Sie sie. Das Ruby-Skript kommuniziert mit dem Spiel während des Flugs, indem es die spezielle Datei erstellt, nach der das Befehlszeilenmodul sucht, und die gewünschten Befehle in die Syntax einfügt, die die Befehlszeile darin versteht.

Ich habe momentan keine kontinuierliche Integration für dieses Projekt verwendet, aber nichts würde mich daran hindern, dieses Ruby-Skript zu erweitern, um auch die generierten Leistungsprotokolle zu analysieren und zu erstellen xUnit- kompatibles XML für die Kommunikation mit dem CI-System zu erstellen, wenn die Leistung unerwartet ist aus irgendeinem Grund durcheinander geraten und das Skript für jeden vollständigen Build auf dem Build-Server ausführen.

Okay, mein Spiel ist weder in XNA geschrieben (es ist einfach C ++ und DirectX), noch respektiert dieser Ansatz die Tatsache, dass Sie es eigentlich nicht wollen das Spiel auf Ihrem Build-Server ausführen . Es ist auch bei weitem nicht so flexibel wie das, was Sie wahrscheinlich wollen - aber es ist dennoch ein ordentlicher, Low-Tech-Ansatz für die automatisierte Leistungsmessung, der etwas CI-freundlich ist (vorausgesetzt, man hat einen bulligen Build-Server).

Bearbeiten: Wie weit ich diesen Ansatz tatsächlich gebracht habe - ich vergleiche nur Leistungsmessungen, die aus verschiedenen Implementierungen nur dieses einen Moduls gewonnen wurden. Das gesamte System ist jedoch so eingerichtet, dass ich jede einzelne der für mein Lightweight-Profiling-Framework definierten Kategorien ausgeben und die Ergebnisse mithilfe der externen Skriptumgebung auf die Art und Weise interpretieren kann, die hier und da nützlich erscheint. Ich beabsichtige weiterhin, den Aspekt der Leistungsprofilierung aus der Gleichung herauszunehmen

  • Überprüfen Sie die Gültigkeit / Konsistenz aller Assets, indem Sie alle Karten mit allen Modellen / Texturen / Sounds laden und die Engine-Protokolle auf ungewöhnliche Ereignisse überprüfen
  • Testen Sie den Motor einem Stresstest und überwachen Sie die Protokolle über einen Zeitraum von mehreren Stunden / Tagen auf unerwartetes Verhalten
Koarl
quelle
1
Alle guten Infos haben dir +1 gegeben. Nach den Geräuschen könnte alles, was Sie oben tun, leicht in einer Art Integrationstest durchgeführt werden. Das einzige, worüber Sie sich Sorgen machen müssen, ist, das eigentliche Spiel / die Simulation zu verspotten. Da Sie genau richtig sind, wenn Sie Ihre Engines / Frameworks-Komponenten isolieren, damit sie in ihrem eigenen Kontext getestet werden können, versuche ich, dies zu erreichen. Da ich mein Spiel nicht auf Leistung testen möchte, da sich das ständig ändert, ändert sich das Framework jedoch selten und kann einfach so eingerichtet werden, dass eine bestimmte Anzahl von Szenarien ausgeführt wird, wie Sie es erwähnen.
Grofit
Vielen Dank. Wie aus den Dingen hervorgeht, die ich in Zukunft erreichen möchte, zielte ich darauf ab, Dinge zu automatisieren, die im realen Spiel passieren. Das Ergebnis war zufällig auch für Leistungsmessungen recht praktisch.
Koarl
0

Ich sehe nicht, was Sie als hilfreiches Werkzeug beschreiben. Als Entwickler ist eine einfache Leistungszahl fast nutzlos.

Was Sie wollen, ist, Ihren Code zu profilieren, ihn in logische Teile aufzuteilen und zu messen, wie viel Zeit jeder von ihnen verwendet, Spitzenwert und Durchschnitt. Jetzt können Sie feststellen, welcher Teil des Codes Probleme verursacht, und wissen, wo Sie nach Optimierungen suchen müssen.

Der schwierige Teil ist nicht, dass sich die Leistung von einem Build zum anderen ändert. Sie benötigen keine Automatisierung, um dies herauszufinden. Der schwierige Teil sind Leistungsunterschiede zwischen verschiedenen Computern. Es gibt keine Möglichkeit, die Leistung von einem Computer auf einen anderen mit unterschiedlichen Grafikkarten usw. zu extrapolieren.

Was Sie also wollen, ist eine Benchmark-Funktion, mit der Sie mit einem Klick die Profilnummern abrufen können. Auf diese Weise können Sie mehrere Maschinen gleichzeitig testen. Es gibt verschiedene Möglichkeiten, dies zu tun. Sie können beispielsweise die Benutzereingaben überschreiben, um einer normalen Spielsitzung so nahe wie möglich zu kommen.

Möglicherweise möchten Sie auch einen längeren Test durchführen, um Speicherlecks zu erkennen.

aaaaaaaaaaaa
quelle
3
Wenn Sie einen typischen CI-Ansatz verfolgen, bei dem Sie Ihre Software über einen Build-Server ausführen, testen Sie immer auf demselben Computer, also immer auf derselben Hardware, wodurch Sie eine Basis für Ihre Zahlen erhalten. Da dies die Richtung war, aus der ich wirklich kam. Sie sagen, dass Sie kein Tool benötigen, um Leistungsänderungen zwischen Builds herauszufinden. Sie können es zwar selbst ausführen und den Unterschied erkennen, aber es wäre großartig, wenn Ihr Build-System oder Ihr aktueller Computer Ihnen diese Zahlen ohne Sie geben könnten etwas anderes zu tun als einen Test durchzuführen.
Grofit
Wenn Sie das Testen am wenigsten ernst nehmen, benötigen Sie mehrere verschiedene Testmaschinen. Was ist auf jeden Fall das eigentliche Problem? Sind Sie sich nicht sicher, wie Sie einen Benchmark in das Spiel einbinden sollen?
aaaaaaaaaaaa
Es gibt kein Problem als solches, ich versuche nur, einige Informationen darüber zu erhalten, wie einige Leute dies auf ihre Projekte angewendet haben. Ich denke nicht, dass separate Computer in irgendeiner Weise hilfreich sind, da Sie nicht wirklich testen, ob sie mit 30 fps auf niedriger Hardware und 60 fps auf schneller Hardware ausgeführt werden. Sie nehmen die Hardware aus der Gleichung und betrachten REIN Ihren Engine- / Quellcode. Eigentlich sollte es keine Rolle spielen, ob Sie auf einem 486 oder einem Quad-Core testen, da Sie einen Build gegen einen anderen testen, nicht einen Hardwaresatz gegen einen anderen.
Grofit
3
Ich muss sowohl Grofit als auch eBusiness in diesem Punkt ein wenig zustimmen. Automatisierte Tests sind besonders bei großen Projekten wichtig, damit Sie bei jedem Build wissen, ob etwas die Leistung beeinträchtigt oder verbessert hat. Dies geschieht idealerweise auf einem Computer. Zumindest bei PC-Spielen müssen Sie auch eine Vielzahl von Hardware testen. Ihre automatisierten Tests sagen möglicherweise, dass die Leistung großartig ist, aber dann führen Sie Ihr Spiel auf einer alten GPU aus oder stellen fest, dass Sie in den virtuellen Speicher und plötzlich in Ihre Leistungstanks geraten. Sie müssen in der Lage sein, diese Dinge zu testen, bevor sie in die Hände der Kunden gelangen.
Nic Foster
@Grofit Die Sache ist, es kann nur die alte Maschine sein, die den Build bricht. Es ist nicht ungewöhnlich, dass eine Änderung keinen signifikanten Leistungseffekt auf einem neuen Computer hat oder sogar eine Verbesserung darstellt, während dieselbe Änderung das Spiel vollständig daran hindert, auf einem alten Computer ausgeführt zu werden. Sie können die Hardware nicht aus der Gleichung herausnehmen, es gibt keine isolierte Codeleistung. Wenn Sie jedoch einen automatisierten Testlauf auf nur einem Computer einrichten möchten, tun Sie dies zumindest auf einem alten Junker. Dadurch haben Sie eine bessere Chance, dass der Test fehlschlägt.
aaaaaaaaaaaa