Wo ich gearbeitet habe, verwenden wir immer mehrere Ebenen der Profilerstellung. Wenn Sie ein Problem feststellen, blättern Sie einfach ein bisschen weiter nach unten, bis Sie herausgefunden haben, was los ist:
- Der "menschliche Profiler", auch bekannt als " nur spielen" ; Fühlt es sich gelegentlich langsam oder "hitch" an? Ruckelige Animationen bemerken? (Beachten Sie als Entwickler, dass Sie für einige Arten von Leistungsproblemen sensibler und für andere weniger empfänglich sind. Planen Sie zusätzliche Tests entsprechend.)
- Schalten Sie die FPS-Anzeige ein , bei der es sich um eine durchschnittliche FPS von 5 Sekunden im Schiebefenster handelt. Sehr wenig Aufwand zum Berechnen und Anzeigen.
- Aktivieren Sie die Profilleisten , bei denen es sich nur um eine Reihe von Quads (ROYGBIV-Farben) handelt, die verschiedene Teile des Frames darstellen (z. B. Leerzeichen, Preframe, Aktualisierung, Kollision, Rendern, Postframe), indem Sie einen einfachen Stoppuhr-Timer um jeden Codeabschnitt verwenden . Um zu betonen, was wir wollen, setzen wir einen Balken mit einer Bildschirmbreite, der für einen 60-Hz-Zielrahmen repräsentativ ist. So ist es wirklich leicht zu erkennen, ob Sie beispielsweise 50% unter dem Budget (nur einen halben Balken) oder 50% über dem Budget ( Die Leiste wird zu anderthalb Leisten. Es ist auch ziemlich einfach zu erkennen, was im Allgemeinen den größten Teil des Frames ausmacht: Rot = Rendern, Gelb = Aktualisieren usw.
- Erstellen Sie einen speziellen instrumentierten Build , der "Stoppuhr" -ähnlichen Code um jede Funktion einfügt. (Beachten Sie, dass Sie dabei unter Umständen einen massiven Performance-, Dcache- und Icache-Schlag erleiden müssen. Dies ist auf jeden Fall aufdringlich. Wenn Sie jedoch keinen ordnungsgemäßen Sampling-Profiler oder keine angemessene Unterstützung für die CPU haben, ist dies eine akzeptable Option. Sie können auch clever sein über das Aufzeichnen eines Minimums an Daten bei der Eingabe / Ausgabe von Funktionen und das spätere Wiederherstellen von Aufrufen.) Als wir unsere erstellten, ahmten wir einen Großteil des Ausgabeformats von gprof nach .
- Führen Sie am besten einen Stichproben-Profiler aus . VTune und CodeAnalyst sind für x86 und x64 verfügbar. Sie haben verschiedene Simulations- oder Emulationsumgebungen, die Ihnen hier möglicherweise Daten liefern.
(Es gibt eine lustige Geschichte aus der GDC eines Grafikprogrammierers aus dem vergangenen Jahr, der vier Bilder von sich selbst gemacht hat - fröhlich, gleichgültig, genervt und wütend - und in der Ecke der internen Builds ein entsprechendes Bild basierend auf der Framerate angezeigt hat Inhaltsersteller lernten schnell, komplizierte Shader nicht für alle ihre Objekte und Umgebungen zu aktivieren: Sie würden den Programmierer verärgern.
Beachten Sie, dass Sie auch lustige Dinge tun können, wie die "Profilleisten" fortlaufend grafisch darstellen, so dass Sie Spitzenmuster ("wir verlieren alle 7 Bilder ein Bild") oder ähnliches sehen können.
Zur Beantwortung Ihrer Frage direkt, aber: in meiner Erfahrung, während es verlockend (und oft belohnt - ich in der Regel etwas lernen) einzelne Funktionen / Module zur Optimierung der Anzahl von Befehlen oder icache oder dCache Leistung neu zu schreiben, und wir tatsächlich brauchten zu tun Dies ist manchmal der Fall, wenn wir ein besonders unangenehmes Leistungsproblem haben. Die überwiegende Mehrheit der Leistungsprobleme, mit denen wir uns regelmäßig befassen, hängt vom Design ab . Beispielsweise:
- Sollten wir im RAM zwischenspeichern oder die "Angriffs" -Status-Animations-Frames für den Player von der Festplatte neu laden? Wie wäre es mit jedem Feind? Wir haben keinen RAM, um sie alle zu erledigen, aber das Laden von Festplatten ist teuer! Sie können das Hitching sehen, wenn 5 oder 6 verschiedene Feinde gleichzeitig hereinkommen! (Okay, wie wäre es mit taumelndem Laichen?)
- Führen wir eine einzelne Operation für alle Partikel oder für alle Operationen für ein einzelnes Partikel aus? (Dies ist ein Icache / Dcache-Kompromiss, und die Antwort ist nicht immer klar.) Wie wäre es, wenn Sie alle Partikel auseinander ziehen und die Positionen zusammen speichern (die berühmte "Struktur von Arrays") und alle Partikeldaten an einem Ort aufbewahren (" Array von Strukturen ").
Sie hören es, bis es in irgendwelchen Informatikkursen auf Universitätsniveau unangenehm wird, aber: es dreht sich wirklich alles um die Datenstrukturen und Algorithmen. Wenn Sie etwas Zeit mit dem Entwurf von Algorithmen und Datenflüssen verbringen, werden Sie im Allgemeinen mehr fürs Geld bekommen. (Vergewissern Sie sich, dass Sie die hervorragenden Fallstricke objektorientierter Programmierung von einem Sony Developer Services-Kollegen gelesen haben, um sich hier einen Überblick zu verschaffen .) Das "fühlt" sich nicht nach Optimierung an. Die meiste Zeit wird mit einem Whiteboard oder UML-Tool verbracht oder es werden viele Prototypen erstellt, anstatt den aktuellen Code schneller laufen zu lassen. Aber es lohnt sich in der Regel viel mehr.
Und noch eine nützliche Heuristik: Wenn Sie sich dem "Kern" Ihrer Engine nähern, lohnt es sich möglicherweise, zusätzliche Anstrengungen und Experimente zu unternehmen, um diese zu optimieren (z. B. diese Matrixmultiplikationen zu vektorisieren!). Je weiter Sie vom Kern entfernt sind, desto weniger sollten Sie sich darüber Gedanken machen, es sei denn, eines Ihrer Profilerstellungstools teilt Ihnen etwas anderes mit.