Performance beschreibt, wie flüssig Ihr Projekt auf Ihrer Ziel-Hardware läuft. Unreal Engine simuliert Echtzeit, indem wiederholt ein Bild des Spiels auf Ihrem Bildschirm gezeichnet bzw. gerendert wird. Wie bei einem Daumenkino zeigt die Engine Frames in schneller Abfolge an, wodurch der Effekt von Bewegung entsteht. Die Performance der gerenderten Frames kann auf zwei Arten gemessen werden: als Frames pro Sekunde und durch einen Blick auf die Framezeit. Das kann Ihnen helfen, die Performance Ihrer Anwendung zu verstehen, um eine bestimmte Anzahl von Frames pro Sekunde anzupeilen, und wo die Zeit innerhalb dieser Frames verbracht wird, was in Millisekunden gemessen wird.
Je mehr Frames Sie in einer Sekunde rendern, desto gleichmäßiger sieht die Bewegung für den Nutzer aus und desto reaktionsschneller fühlt sich die Anwendung an. Im Allgemeinen zielen Anwendungen auf 30, 60 und 120 Frames pro Sekunde ab, wenn man ihr Performance-Budget und die Zielhardware bedenkt. Um dem Nutzer das bestmögliche Erlebnis zu bieten, sollte die Framerate höher, aber auch konsistent sein. Dieses Dokument bietet eine Einführung in Überlegungen zur Rendering-Performance sowie einen Walkthrough verschiedener Werkzeuge, mit denen Sie die Rendering-Performance Ihrer Unreal-Engine-Anwendung analysieren und verwalten können.
Verstehen der Performance
Viel Logik in Unreal Engine hängt von zwei Dingen ab:
Was im aktuellen Frame passiert
Wie viel Zeit seit dem vorherigen Frame vergangen ist
Beim Rendern eines Frames kann zum Beispiel Folgendes passieren:
Der Nutzer kann einen Charakter oder ein Fahrzeug bewegen.
Der Benutzer kann mit einem Objekt interagieren.
KI-gesteuerte Entitäten können sich bewegen oder verschiedene Aktionen ausführen.
Die Benutzeroberfläche des Nutzers kann sich ändern.
Ein Objekt auf dem Bildschirm kann in seiner Animation vorwärts schreiten oder möglicherweise mehrere Animationen mischen.
Physik-Simulationen können die Position oder Drehung von Physik-Objekten verändern.
Jede dieser Operationen erhöht die Arbeit Ihres Computer, während er jeden Frame zeichnet. Außerdem können Sie den Prozess des Zeichnens jedes Frames mit einer Reihe von Rendering-Einstellungen mehr oder weniger komplex gestalten. Im Folgenden finden Sie einige mögliche Anpassungen:
Sie erhöhen die Details von Objekten und Texturen, wodurch Ihr Computer mehr Zeit bei der Berechnung der finalen Farbe jedes einzelnen Pixels braucht.
Fügen Sie Nachbearbeitungseffekte hinzu, die jeweils zusätzliche Durchläufe erfordern, die in verschiedenen Phasen des Renderings auf das Bild angewendet werden müssen.
Verwenden Sie eine realitätsnähere Beleuchtung und Schattierung, was die Szenen realistischer aussehen lässt, aber auch die Komplexität der Beleuchtungsberechnungen erhöht.
Je mehr Aufgaben Sie Ihrer Anwendung pro Frame auferlegen, desto länger dauert das Rendern eines einzelnen Frames. Wenn Ihre Frames besonders lange zum Rendern brauchen, verlangsamt sich die gesamte Framerate, wodurch Ihre Anwendung weniger flüssig aussieht und weniger reaktionsschnell ist.
Messung von Frames pro Sekunde und Frame-Zeit
Um die Frames pro Sekunde und die Framedauer zu verfolgen, können Sie diese Messungen im Viewport anzeigen lassen. Aktivieren Sie im Hamburger-Menü des Viewports FPS anzeigen, klicken Sie auf Statistik > Engine und aktivieren Sie FPS und Einheit.
Hardware-Einschränkungen und Framerate-Drops
Eine langsame Framerate ist das Ergebnis von zu vielen Verarbeitungsvorgängen, die während eines einzelnen Frames stattfinden, normalerweise durch Operationen, die sich jedes Mal wiederholen, wenn ein Frame auf dem Bildschirm gezeichnet wird. Sie können sich jeden Frame, den Sie rendern, als einen Zug vorstellen, den Sie zum Verlassen des Bahnhofs einplanen, gefolgt von einem anderen Zug ein paar Millisekunden später. Bei diesem Zug müssen jedoch alle Fahrgäste, die eine Fahrkarte gekauft haben, in den Zug einsteigen, bevor er abfahren kann. Jede Operation, die Sie während dieses Frames durchführen, sei es Gameplay oder Rendering-Logik, ist wie ein weiterer Passagier, der an Bord kommen muss.
Wenn man zu viel Zeit mit der Bearbeitung eines einzelnen Frames verbringt, ist das so, als würde man den Zug aufhalten, weil man versucht, zu viele Fahrgäste einsteigen zu lassen, die noch nicht alle eingestiegen sind. Dadurch wird verhindert, dass der nächste Zug einfahren kann. Das Ergebnis auf dem Bildschirm ist ein Framerateabfall. Diese können kurzzeitig auftreten, was zu Hitches führt, bei denen der Bildschirm einen Moment zu lange an einem Bild hängen bleibt, oder sie können konstant bei jedem Bild auftreten, was zu einer insgesamt niedrigen Framerate führt.
Jede der folgenden Rechenressourcen kann potenziell einen Engpass verursachen:
CPU: Die zentrale Verarbeitungseinheit (CPU) Ihres Computers führt zu viele Operationen auf einem oder mehreren Threads während eines einzelnen Frames aus. Dies deutet darauf hin, dass die Benutzeroberfläche, die Spiellogik oder eine andere Kernlogik Ihrer Anwendung ineffizient ausgeführt werden oder dass Sie zu viele dieser Vorgänge während eines einzelnen Frames durchführen.
GPU: Die Grafikverarbeitungseinheit (GPU) Ihres Computers führt zu viele Operationen während eines einzelnen Frames aus. Dies deutet darauf hin, dass das Rendering oder die Nachbearbeitung Ihres Spiels ineffizient abläuft oder dass die GPU anderweitig mit zu vielen Operationen belastet ist, als dass sie mithalten könnte.
Arbeitsspeichergröße (RAM): Der Arbeitsspeicher (RAM) Ihres Computers ist voll, so dass keine Operationen mehr ausgeführt werden können, bis er geleert wird. Dies führt in der Regel eher zu einer „Speicher voll“-Ausnahme und einem Absturz als zu einem Leistungsproblem. Einige Systeme wie die Garbage Collection oder das Asset Streaming sind elastisch, was die Aufräumarbeiten dynamisch verzögert. Wenn der Arbeitsspeicher voll ist, müssen solche Systeme häufiger Bereinigungs- und Neubesetzungsvorgänge durchführen, was die CPU zusätzlich belastet.
Arbeitsspeichergeschwindigkeit (RAM): CPUs arbeiten mit kleinen Datenpaketen, die physisch mit den Kernen verbunden sind, und tauschen diese Datenpakete bei Bedarf mit dem RAM aus. Diese Operationen können sehr viel schneller ablaufen als der Austausch von Paketen zwischen der CPU und dem Arbeitsspeicher (eine CPU kann z. B. 20 Manipulationen an geladenen Daten in der gleichen Zeit durchführen, die für das Laden eines neuen Datenteils benötigt wird). Je langsamer der Arbeitsspeicher ist und je häufiger die Logik zwischen den zusammenhängenden Speicherbereichen, mit denen sie interagieren muss, umschalten muss, desto mehr Zeit verbringen die CPU-Kerne mit Nichtstun, während sie auf den Speicherbus warten.
GPU Speicher (VRAM): Der Arbeitsspeicher Ihrer GPU ist voll und verhindert, dass Operationen ausgeführt werden, bis er geleert wird. Dies ist in der Regel auf eine Überlastung des Texturspeichers zurückzuführen, da Texturen sehr viel Speicherplatz benötigen.
Festplattenzugriff: Objekte müssen von der Festplatte oder einem anderen Speichermedium geladen werden, bevor sie dem Speicher hinzugefügt werden können. Wenn Sie sehr häufig auf Ihr Speichermedium zugreifen müssen, kann dies dazu führen, dass Vorgänge nicht abgeschlossen werden können.
Netzwerk-Bandbreite: Die Internetverbindung Ihres Computers ist langsam oder unzuverlässig, was dazu führt, dass bei jedem Frame mehr CPU-Arbeit für das Zusammensetzen oder erneute Senden zuverlässiger Pakete aufgewendet werden muss, dass Arbeit, die sonst auf viele Frames hätte verteilt werden können, in Stoßzeiten anfällt oder dass das Bildmaterial trotz fehlender lokaler Leistungsengpässe einfach abgehackt ist.
CPU-gebunden vs. GPU-gebunden
Wir beschreiben Anwendungen so, dass sie entweder an die CPU oder an die GPU gebunden sind, je nachdem, welche von beiden den geringeren Spielraum für die Performance hat. Wenn es bei Ihrer CPU eher zu Engpässen kommt, ist es CPU-gebunden. Wenn es bei Ihrer GPU eher zu Engpässen kommt, ist es GPU-gebunden. Wenn Sie Vsync aktiviert haben und sowohl die CPU als auch die GPU in der Lage sind, Frames schneller zu produzieren, als der Monitor sie anzeigen kann, wäre Ihre Anwendung Anzeige-gebunden. Dies hängt oft von der Zielplattform und ihren Ressourcen ab.
Verarbeitungsspitzen
Eine Spitze bei der Verarbeitung bezieht sich auf einen plötzlichen, kurzen Anstieg der Zeit, die entweder Ihre CPU oder Ihre GPU während eines Frames benötigt.
Teure vs. kostengünstige Operationen
Allgemein ausgedrückt, eine kostenintensive Operation erfordert eine relativ große Menge an Rechenressourcen zur Ausführung. Dies könnte eine höhere Verarbeitungszeit oder einen höheren Speicherbedarf bedeuten. Kostengünstige Operationen erfordern keine große Menge an Rechenressourcen. Diese Begriffe werden häufig verwendet, um Prozesse zu vergleichen, die ähnliche Vorgänge ausführen.
Speicher in Echtzeit-Anwendungen
Alles, was Sie verarbeiten oder rendern können, befindet sich im Speicher Ihrer Anwendung, mit einigen Ausnahmen wie z. B. virtuelle Geometrie in Nanite, die direkt von einer Solid State Hard Drive (SSD) gestreamt wird. Wenn Sie das Objekt auf dem Bildschirm sehen und bewegen können, existiert eine Kopie davon im Speicher Ihres Computers, und die Rendering-Ressourcen des Objekts, wie Texturen, Shader und Meshes, befinden sich im Speicher Ihrer GPU.
Performance und Stromverbrauch
Der Stromverbrauch variiert je nach Hardware-Architektur, aber im Allgemeinen tragen sowohl eine höhere Verarbeitungslast als auch das Rendern von mehr Frames pro Sekunde zu einem höheren Stromverbrauch bei. In mobilen und HMI-Umgebungen ist der Stromverbrauch Ihres Geräts ein wichtiger Faktor, daher sind Sie stark dazu angehalten, Ihre Anwendung so effizient wie möglich zu gestalten. Spieler können Spiele, die den Akku ihres Telefons schneller verbrauchen als andere Spiele, negativ bewerten. Außerdem kann die Erwärmung des Telefons durch einen höheren Energieverbrauch zu einer thermischen Drosselung führen, die die CPU zwingt, langsamer zu arbeiten, bis das Telefon wieder abgekühlt ist.
Profiling Werkzeuge
Unter Profiling versteht man die Analyse der Nutzung von Systemressourcen durch Ihre Anwendung, z. B. CPU- oder GPU-Verarbeitung, Speichernutzung oder Netzwerkbandbreite. Unreal Engine bietet mehrere Sets von Profiling-Werkzeugen:
Werkzeug | Beschreibung |
Unreal Insights | Zeichnen und überprüfen Sie die Performance-Daten auf einer Frame-by-Frame-Basis auf. |
Statistik-Befehle | Performance-Statistiken auf dem Bildschirm anzeigen. |
Informationen zur Verwendung von Unreal Insights mit Android Geräten finden Sie auf der Seite Unreal Insights on Android Devices.
Sie können auch ein Werkzeug eines Drittanbieters für das Profiling verwenden, darunter die folgenden:
Werkzeug | Beschreibung |
RenderDoc | Debuggen Sie Einzel-Frame-Aufnahmen der Grafiken Ihrer Anwendung. |
Erstellen Sie ein vollständiges Systemprofil und verarbeiten Sie Trace-Daten. |
Beachten Sie, dass das Profiling dieselbe CPU, denselben RAM und Festplatte verwendet, die auch das Spiel verwendet. Wenn Sie Ihr Spiel mit einem angehängten Profiler ausführen, wird die Performance etwas schlechter sein. Das kann aber auch eine gute Sache sein, da es zu einem Szenario führt, in dem das scheinbare Erreichen der Performance-Ziele in Wirklichkeit bedeutet, dass man sie übertroffen hat, so dass einige freie Ressourcen übrig bleiben, mit denen das Spiel bei unvorhergesehenen Systemschwankungen auf Kurs bleiben kann.
Unreal Insights
Unreal Insights ist eine robuste und leistungsstarke Suite von Profiling-Werkzeugen, die in der Unreal Engine zur Verfügung stehen und Werkzeuge für das Profiling einzelner Threads, der Speichernutzung und der Netzwerkbandbreite bieten. Sie können sehen, wie viele Millisekunden jeder einzelne Vorgang auf der CPU oder GPU benötigt, wie viel Speicher in Speicher-Insights zugewiesen wird und eine Aufschlüsselung der Telemetrie- und Paketdaten in Netzwerk-Insights. Es gibt auch spezielle Modi für das Profiling von Aufgabendiagrammen, Kontextwechseln und Slate-UI-Elementen, die Ihnen helfen können, eine gründliche Analyse der Performance Ihrer Anwendung durchzuführen.
Statistik-Befehle
Statistiken bezieht sich auf eine Reihe von Konsolenbefehlen, die Sie innerhalb einer laufenden UE-Anwendung verwenden können, zum Output von Statistiken auf dem Bildschirm. Es gibt Statistikbefehle für eine Vielzahl von Operationen und Systemen, einschließlich, aber nicht beschränkt auf:
Speicherverfolgung
GPU- und CPU-Auslastung
Gameplay-Ticks
UI
Animationen
Die Verwendung der Statistikbefehle ist zwar nicht so stabil wie die Arbeit mit Unreal Insights oder RenderDoc, aber es ist der schnellste Weg, um Daten darüber zu erhalten, was in Ihrer Anwendung passiert, während Sie sie ausführen oder testen.
Eine vollständige Liste der Statistikbefehle finden Sie auf der Seite Statistikbefehle.
RenderDoc
RenderDoc ist ein Open-Source-Grafik-Debugger, der an UE angehängt werden kann und die Ausgabe von Einzelframe-Aufnahmen ermöglicht. Er kann viele Operationen durchführen, darunter die folgenden:
Prüfen von Texturen, Modellen oder Shadern.
Individuelle Draw-Events anzeigen.
Bereitstellung einer Aufschlüsselung des Pipeline-Status Ihrer Anwendung in dem Moment, in dem Sie einen Frame erfassen.
Während Unreal Insights Ihnen eine allgemeine Vorstellung davon vermitteln kann, welche Rendering-Operationen den größten Teil der Verarbeitungs- und Speicherressourcen beanspruchen, eignet sich RenderDoc eher für eine detaillierte Diagnose der Rendering-Vorgänge und zum Aufspüren der exakten Stellen, an denen Bugs auftreten. Wenn Sie beispielsweise Rendering-Artefakte auf Ihrem Zielgerät, aber nicht im Play-In-Editor sehen, können Sie mit RenderDoc einen Frame auf beiden Geräten erfassen, die Daten vergleichen und herausfinden, was die Artefakte verursacht.
Performance- Konfigurations-Werkzeuge
Viele Anweisungen zum Anpassen Ihres Projekts an die Rendering- und scalability settings beziehen sich auf Konsolenbefehle und Variablen. In diesem Abschnitt finden Sie eine Einführung in ihre Verwendung und Ressourcen für ein tieferes Verständnis.
Konsolenbefehle und Variablen
Die Konsole ist eine Befehlszeile innerhalb der Unreal Engine, mit der Sie Einstellungen ändern, Debug-Befehle ausführen und Informationen abrufen können, während das Spiel läuft. Sie können Konsolenbefehle im Unreal Editor oder in einem Entwickler- oder Debug Build eines verpackten Projekts verwenden, indem Sie die Taste Tilde (~) drücken. Dies öffnet die Befehlszeile und fordert Sie auf, Ihren Befehl einzugeben.
Befehle in der UE unterstützen eine Such-/Autovervollständigungs-Funktion, so dass Sie einen Teilbefehl eingeben können, um eine Liste der möglichen Befehle einzugrenzen, nach denen Sie suchen. Wenn Sie z. B. Statistik eingeben, wird eine Liste von Statistikbefehlen angezeigt.
Konsolenvariablen, oder CVARs, sind Konfigurationsvariablen, die Sie mit Konsolenbefehlen bearbeiten können. Sie können CVARs direkt in der Konsole ändern, indem Sie den Konfigurationspfad der Variable eingeben und dann den Wert angeben, auf den Sie die Variable setzen wollen. Zum Beispiel:
r.TemporalAA.Quality 0
Der obige Befehl setzt den CVAR r.TemporalAA.Quality
auf 0 und deaktiviert damit effektiv temporales Anti-Aliasing. Dadurch erscheinen die Kanten von Objekten mehtr star und mehr verpixelt.
Weitere Informationen über die Konsole finden Sie auf den folgenden Seiten:
Console Variables and Commands – Ein Überblick über das Arbeiten mit der Konsole im Detail.
Console Commands Reference – Eine vollständige Liste von Konsolenbefehlen.
Console Variables Reference – Eine vollständige Liste von Konsolenvariablen.
Console Variables Editor – Ein Plugin um Konsolenvariablen direkt im Unreal Editor zu bearbeiten.
Sie können auch Konsolenbefehle in Blueprint und C++ verwenden, um Variablen jederzeit zu ändern, selbst wenn die Konsole in den ausgelieferten Builds deaktiviert ist. Dies kann für die selektive Skalierung Ihrer Einstellungen während der Ausführung Ihrer Anwendung nützlich sein.
Output-Log
Wenn Sie mit der Konsole im Unreal Editor arbeiten, ist es einfacher zu verstehen, was vor sich geht, wenn Sie das Output-Log anzeigen, das eine Aufzeichnung der Befehle und Logs enthält.
Um das Output-Log im Unreal Editor einzusehen, klicken auf Fenster > Output-Log. Das Output-Log dwird dann am unteren Rand Ihres Editors angedockt.
Gespeicherte Log-Dateien erscheinen im Ordner Saved/Logs
Ihres Projekts.
Konfigurationsdateien
Konsolenvariablen werden in Ihren Konfigurationsdateien (.ini
) als Key-Wert-Paare gespeichert und bieten Standardeinstellungen für Builds Ihres Spiels. Weitere Informationen finden Sie unter Configuration Files.
Geräteprofile
Geräteprofile sind Konfigurationsdateien, die Einstellungen für ein bestimmtes Gerät enthalten, für das Ihr Projekt bestimmt ist. Dies kann so weit gefasst sein wie ein großer Bereich von Geräten, z. B. Android_Mid
, oder so präzise wie einzelne Teile von Hardware. Jedes Geräteprofil verfügt über eine Reihe von Einstellungsüberschreibungen, die nur für das jeweilige Gerät gelten.
Die Geräteprofile der Unreal Engine beziehen sich hauptsächlich auf GPU-Familien wie die Adreno 7xx-Serie, aber Sie können eigene Geräteprofile hinzufügen und Regeln für die unterstützte Hardware definieren.
Weitere Informationen finden Sie unter Customizing Device Profiles and Scalability on Android.
Weitere Informationen
Weitere Informationen über Situationen und Faktoren, die die Performance Ihrer Anwendung beeinträchtigen können, finden Sie unter Common Performance Considerations.
Tipps und Optimale Vorgehensweisen
Frühzeitig testen und oft testen
Rechnen Sie beim Testen damit, dass Ihr Projekt auf Fehler stoßen wird, die für jede einzelne von Ihnen unterstützte Plattform spezifisch sind. Obwohl der Unreal Editor bestrebt ist, eine genaue Vorschau zu liefern, gibt es keinen Ersatz für ein Profiling direkt auf Ihrer Zielhardware. Je länger Sie Ihre Hardware nicht testen, desto wahrscheinlicher ist es, dass Fehler auftauchen, deren Sie sich nicht bewusst sind.