Freigeben über


Profilieren von DirectX-Apps

Hier erfahren Sie, wie Sie einige der wichtigsten Leistungszeitmessungen für eine DirectX-App mithilfe der XPerf - und GPUView-Tools messen, die als Teil des Windows Performance Toolkits ausgeliefert werden. Dies ist kein umfassender Leitfaden für das Verständnis der Tools, sondern ihre spezifische Anwendbarkeit für die Analyse der DirectX-App-Leistung. Während die meisten der hier beschriebenen Techniken für alle DirectX-Apps relevant sind, ist es für Apps relevant, die Swapchains verwenden und nicht für DirectX-Anwendungen, die auf XAML basieren, die SIS/VSIS- und XAML-Animationen verwenden. Wir führen Sie durch wichtige Leistungszeiterfassungen, wie Sie die Tools abrufen und installieren, Leistungsmesstraces erstellen und sie dann analysieren, um App-Engpässe zu verstehen.

Informationen zu den Tools

XPerf

XPerf ist eine Reihe von Leistungsanalysetools, die auf der Ereignisablaufverfolgung für Windows (ETW) basieren, die für die Messung und Analyse detaillierter System- und App-Leistung und Ressourcennutzung entwickelt wurde. Ab Windows 8 verfügt dieses Befehlszeilentool über eine grafische Benutzeroberfläche und wird als Windows Performance Recorder (WPR) und Windows Performance Analyzer (WPA) bezeichnet. Weitere Informationen zu diesen Tools finden Sie auf der Webseite für das Windows Performance Toolkit (WPT): Windows Performance Toolkit.

Ein ETW sammelt angeforderte Kernelereignisse und speichert sie in einer Datei, die als ETL-Datei (Event Trace Log) bezeichnet wird. Diese Kernelereignisse enthalten umfassende Informationen zu app- und Systemmerkmalen beim Ausführen der App. Daten werden gesammelt, indem die Ablaufverfolgung aktiviert wird, das gewünschte App-Szenario, das analysiert werden muss, ausgeführt wird und die Erfassung beendet wird, wodurch die Daten in einer ETL-Datei gespeichert werden. Anschließend können Sie die Datei auf dem gleichen oder einem anderen Computer analysieren, indem Sie entweder das Befehlszeilentool xperf.exe oder das visuelle Analysewerkzeug für Trace-Daten xperfview.exe verwenden.

GPUView

GPUView ist ein Entwicklungstool zur Ermittlung der Leistung der Grafikverarbeitungseinheit (GPU) und der CPU. Es untersucht die Leistung im Hinblick auf die Direkte Speicherzugriffspufferverarbeitung (DMA) und alle anderen Videoverarbeitungen auf der Videohardware.

Bei DirectX-Apps , die stark auf die GPU angewiesen sind, ist GPUView ein leistungsfähiges Tool zum Verständnis der Beziehung zwischen der Arbeit, die auf der CPU und der GPU ausgeführt wird. Weitere Informationen zu GPUViewfinden Sie unter Verwenden von GPUView.

Ähnlich wie XPerf wird eine ETW-Ablaufverfolgung durchgeführt, indem man zuerst den Ablaufverfolgungsdienst startet, dann das Szenario für die zu analysierende App ausführt, den Dienst beendet und die Informationen in einer ETL-Datei speichert. GPUView stellt die Daten in der ETL-Datei in einem grafischen Format dar.

Nach der Installation des GPUView-Tools wird empfohlen, das Thema "GPUView Hauptanzeige" im Menü "GPUView-Hilfe " zu lesen. Es enthält nützliche Informationen zum Interpretieren der GPUView-Benutzeroberfläche .

Installieren der Tools

Sowohl XPerf als auch GPUView sind im Windows Performance Toolkit (WPT) enthalten.

XPerf wird als Teil des Windows Software Development Kit (SDK) für Windows ausgeliefert. Laden Sie das Windows SDKherunter.

GPUView ist im Windows Assessment and Deployment Kit (Windows ADK) verfügbar. Laden Sie das Windows ADK herunter.

Nach der Installation müssen Sie die Verzeichnisse, die XPerf und GPUView enthalten, der Systemvariablen "Path" hinzufügen.

Klicken Sie auf die Schaltfläche "Start", und geben Sie "Systemvariablen" ein. Das Fenster "Systemeigenschaften" wird geöffnet. Klicken Sie auf "Systemumgebungsvariablen bearbeiten". Wählen Sie im Dialogfeld "Systemeigenschaften" die Option "Umgebungsvariablen" aus. Die Variable "Path" befindet sich unter "Systemvariablen". Fügen Sie das Verzeichnis an, das xperf.exe und GPUView.exe enthält, an den Pfad. Diese ausführbaren Dateien befinden sich im Verzeichnis "Windows Performance Toolkit" in den "Windows Kits". Der Standardspeicherort lautet: C:\Programme (x86)\Windows Kits\10\Windows Performance Toolkit.

Leistungszeitmessungen

Die meisten Apps erwarten eine reibungslose Ausführung und reagieren auf Benutzereingaben. Je nach gewünschtem Szenario kann ein Aspekt der Leistung jedoch wichtiger sein als ein anderer. Für eine Newsreader-App, die auf einem Touch-Tablet-PC ausgeführt wird, ist beispielsweise der wichtigste Aspekt das Gleichzeitige Anzeigen eines einzelnen Artikels und das Verschieben/Zoomen/Scrollen durch denselben oder einen anderen Artikel. In diesem Szenario ist die Möglichkeit zum Rendern aller Inhalte für jeden Frame nicht erforderlich. Die Möglichkeit zum reibungslosen Scrollen durch den Artikel bei einer Touchgeste ist jedoch äußerst wichtig.

In einem anderen Fall kommt es bei einem Spiel oder einer Video-Rendering-App, die viele Animationen verwendet, zu Störungen, wenn Frames verloren gehen. In diesem Fall ist die Möglichkeit, Inhalte auf dem Bildschirm ohne Unterbrechung der Benutzereingabe darzustellen, äußerst wichtig.

Um zu verstehen, welcher Teil der App problematisch ist, besteht der erste Schritt darin, die wichtigsten Szenarien zu entscheiden. Sobald die wichtigsten Aspekte der App verstanden und wie sie ausgeübt werden, wird die Suche nach Problemen mit den Tools einfacher.

Einige der häufigsten Leistungszeitmetriken sind wie folgt:

Startzeit

Die vom Start des Prozesses gemessene Zeitspanne bis die erste Darstellung auf dem Bildschirm erscheint. Diese Messung ist nützlicher, wenn das System warm ist, was bedeutet, dass die Messung nach dem Starten der App ein paar Mal durchgeführt wird.

CPU-Zeit pro Frame

Die Zeit, für die die CPU die App-Workload aktiv für einen Frame verarbeitet. Wenn die App reibungslos ausgeführt wird, erfolgt die gesamte für einen Frame erforderliche Verarbeitung innerhalb eines v-Synchronisierungsintervalls. Mit der Monitoraktualisierungsrate von 60Hz kommt dies auf 16 ms pro Frame. Wenn CPU-Zeit/Frame größer als 16 ms ist, sind möglicherweise CPU-Optimierungen erforderlich, um eine Glitch free App-Erfahrung zu erzeugen.

GPU-Zeit pro Frame

Die Zeit, für die GPU die App-Workload aktiv für einen Frame verarbeitet. Eine App ist GPU-gebunden, wenn die Verarbeitung eines Frames länger als 16 ms dauert.

Wenn Sie wissen können, ob eine App CPU- oder GPU-gebundene App ist, wird der problematische Teil des Codes eingeschränkt.

Leistungsmessung der Ausführungszeit protokollieren

Führen Sie die folgenden Schritte aus, um eine Ablaufverfolgung durchzuführen:

  1. Öffnen Sie ein Befehlsfenster als Administrator.
  2. Schließen Sie die App, wenn sie bereits ausgeführt wird.
  3. Ändern Sie Verzeichnisse in das Gpuview-Verzeichnis im Ordner "Windows Performance Toolkit".
  4. Geben Sie "log.cmd" ein, um die Ereignisablaufverfolgung zu starten. Diese Option protokolliert die interessantesten Ereignisse. Andere verfügbare Optionen protokollieren unterschiedliche Bereiche der Ereignisse. Zum Beispiel erfasst der ausführliche Protokollmodus, bekannt als 'v', alle Ereignisse, die der GPUView bekannt sind.
  5. Starten Sie das Beispiel, und üben Sie das Beispiel auf eine Weise aus, die den Leistungspfad abdeckt, den Sie analysieren müssen.
  6. Wechseln Sie zurück zu den Befehlsfenstern, und geben Sie erneut "log.cmd" ein, um die Protokollierung zu beenden.
  7. Dadurch wird eine Datei namens "merged.etl" im Gpuview-Ordner ausgegeben. Sie können diese Datei an einem anderen Speicherort speichern und sie auf demselben oder einem anderen Computer analysieren. Um Stapelerfassungsdetails anzuzeigen, speichern Sie die symboldatei (PDB), die der App zugeordnet ist.

Messungen

Hinweis

Die Messungen für geometrierealisierungsbeispiele werden auf einem Quad Core-Computer mit einer integrierten DirectX11-Grafikkarte aufgenommen. Die Messungen variieren je nach Maschinenkonfiguration.

 

In diesem Abschnitt wird veranschaulicht, wie Sie die Startzeit, die CPU- und GPU-Zeit pro Framemaß messen. Sie können eine Leistungsablaufverfolgung für dasselbe Beispiel auf Ihrem Computer erfassen und die Unterschiede in den verschiedenen Messungen sehen.

Um die Ablaufverfolgung in GPUView zu analysieren, öffnen Sie die Datei "merged.elt" mit GPUView.exe.

Startzeit

Die Startzeit wird durch die Gesamtzeit gemessen, die vom Start der App bis zum ersten Erscheinen des Inhalts auf dem Bildschirm vergeht.

Die Startzeitmessung wird am besten durchgeführt, indem Sie die im vorherigen Abschnitt aufgeführten Schritte mit diesen Variationen ausführen:

  • Wenn Sie beim allerersten Start der App die Initialmessungen durchführen, wird dies als Kaltstart bezeichnet. Dies kann von den Messungen variieren, die nach dem Starten der App einige Male in einer kleinen Zeitspanne durchgeführt wurden. Dies wird als warmer Start bezeichnet. Je nachdem, wie viele Ressourcen eine App beim Start erstellt, kann es einen großen Unterschied zwischen den beiden Startzeiten geben. Je nach App-Zielen kann die Messung eines oder des anderen wünschenswert sein.
  • Wenn Sie Leistungsinformationen protokollieren, beenden Sie die App, sobald der erste Frame auf dem Bildschirm angezeigt wird.

Berechnen der Startzeit mithilfe von GPUView

  1. Scrollen Sie in GPUView nach unten zum relevanten Prozess, in diesem Fall GeometryRealization.exe.

    Screenshot, der ein Beispiel für Prozesse in GPUView zeigt.

  2. Die Kontext-CPU-Warteschlange repräsentiert die Grafik-Workload, die der Hardware zur Verarbeitung übergeben wird, aber nicht unbedingt von der Hardware bearbeitet wird. Wenn die Ablaufverfolgungsdatei geöffnet wird, werden alle Ereignisse angezeigt, die zwischen der Erstellung der Ablaufverfolgung protokolliert wurden. Um die Startzeit zu berechnen, wählen Sie den Bereich von Interesse aus, zoomen Sie in den ersten Teil der ersten Kontext-CPU-Warteschlange (dies ist diejenige, die Aktivität zeigt) mit STRG + Z. Weitere Informationen zu GPUView-Steuerelementen finden Sie im Abschnitt "Zusammenfassung der GPUView-Steuerelemente". Die folgende Abbildung zeigt nur den GeometryRealization.exe Prozess, der auf den ersten Teil der Kontext-CPU-Warteschlange hin vergrößert wurde. Die Farbe der Kontext-CPU-Warteschlange wird durch das Rechteck direkt unterhalb der Warteschlange gekennzeichnet, und Datenpakete gleicher Farbe in der Warteschlange zeigen an, dass GPU-Arbeiten auf der Hardware anstehen. Das Schlupfmusterpaket in der Kontextwarteschlange zeigt das vorhandene Paket an, was bedeutet, dass die App den Inhalt auf dem Bildschirm präsentieren möchte.

    Screenshot, der Beispiele für die

  3. Die Startzeit ist die Zeit, zu der die App zum ersten Mal gestartet wird (in diesem Fall das UI-Threadeinstiegspunktmodul SHCORE.dll), bis der Kontext zum ersten Mal angezeigt wird (gekennzeichnet durch ein Schlupfpaket). Die Abbildung hier hebt den Interessensbereich hervor.

    Hinweis

    Die tatsächlich aktuellen Informationen sind in der Flip-Warteschlange repräsentiert, und daher verlängert sich die Zeit, bis das aktuelle Paket in der Flip-Warteschlange tatsächlich abgeschlossen ist.

     

    Die vollständige Statusleiste ist in der Abbildung unten nicht sichtbar, in der auch die verstrichene Zeit zwischen den hervorgehobenen Teilen angezeigt wird. Dies ist die Startzeit der App. In diesem Fall für die oben erwähnte Maschine kam es zu ca. 240 ms.

    Screenshot, der Interessantes zu Startzeit in der

CPU- und GPU-Zeit pro Frame

Es gibt ein paar Dinge, die Sie beim Messen der CPU-Zeit berücksichtigen müssen. Suchen Sie nach den Abschnitten in der Ablaufverfolgung, in denen Sie das zu analysierende Szenario durchgeführt haben. Beispielsweise ist im Geometrie-Realisierungsbeispiel eines der analysierten Szenarien der Übergang zwischen dem Rendern von 2048 und 8192 Primitivelementen, wobei alle nicht realisiert sind, d. h., die Geometrie wird nicht in jedem Frame tesselliert. Die Ablaufverfolgung zeigt eindeutig Unterschiede in der CPU- und GPU-Aktivität vor und nach der Änderung der Anzahl der Primitiven.

Zwei Szenarien werden analysiert, um CPU- und GPU-Zeit pro Frame zu berechnen. Sie sind wie folgt.

  • Übergang vom Rendern 2048 unrealisierter Grundtypen auf das Rendern von 8192 unrealisierte Grundtypen.
  • Der Übergang von der Darstellung von 8192 realisierten Primitiven zu 8192 unrealisierte Primitiven.

In beiden Fällen wurde festgestellt, dass die Bildfrequenz drastisch gesunken ist. Die Messung der CPU- und GPU-Zeit, die Beziehung zwischen den beiden sowie einige andere Muster in der Ablaufverfolgung kann nützliche Informationen zu problematischen Bereichen in der App liefern.

Berechnung der CPU- und GPU-Zeit beim nicht realisierten Rendern von 2048 Primitiven

  1. Öffnen Sie die Ablaufverfolgungsdatei mit GPUView.exe.

  2. Scrollen Sie nach unten zum GeometryRealization.exe-Prozess.

  3. Wählen Sie einen Bereich zum Berechnen der CPU-Zeit aus, und zoomen Sie ihn mit STRG+Z.

    Screenshot eines Bereichs, der für die Berechnung der C P U-Zeit in der Kontext-CPU-Warteschlange ausgewählt ist.

  4. Anzeigen von V-Synchronisierungsinformationen durch Umschalten zwischen F8. Vergrößern Sie weiter, bis es leicht ist, eine vsync Menge von Daten klar zu sehen. Die blauen Linien zeigen, wo die V-Synchronisierungszeiten liegen. In der Regel treten diese einmal alle 16 ms (60 fps) auf, aber wenn DWM ein Leistungsproblem auftritt, wird sie langsamer ausgeführt, sodass sie einmal alle 32 ms (30 fps) auftreten. Um ein Zeitgefühl zu gewinnen, wählen Sie von einem blauen Balken zum nächsten und sehen Sie sich dann die Anzahl der in der unteren rechten Ecke des GPUView-Fensters gemeldeten ms an.

    Screenshot, der ein Beispiel für V-Synchronisierungszeiten zeigt.

  5. Um die CPU-Zeit pro Frame zu messen, messen Sie die Zeitdauer aller Threads, die beim Rendern beteiligt sind. Es kann sinnvoll sein, den Thread einzugrenzen, der aus Leistungsgründen am relevantesten sein wird. Beispielsweise im Beispiel zur Geometrierealisierung wird der Inhalt animiert und muss auf dem Bildschirm jedes Frame gerendert werden, wodurch der UI-Thread zu dem wichtigen wird. Nachdem Sie ermittelt haben, welcher Thread betrachtet werden soll, messen Sie die Länge der Balken in diesem Thread. Durchschnittlich ergibt sich aus einigen dieser Werte die CPU-Zeit pro Frame. Die folgende Abbildung zeigt die verwendete Zeit im Benutzeroberflächen-Thread. Es zeigt auch, dass diese Zeit gut zwischen zwei aufeinander folgenden V-Syncs passt, was bedeutet, dass es 60 FPS erreicht.

    Screenshot, der die beanspruchte Zeit im UI-Thread zeigt.

    Sie können dies auch überprüfen, indem Sie die Flip-Warteschlange des entsprechenden Zeitrahmens betrachten, die zeigt, dass DWM jeden Frame präsentieren kann.

    Screenshot, der ein Beispiel für die

  6. Die GPU-Zeit kann auf die gleiche Weise gemessen werden wie die CPU-Zeit. Zoomen Sie in den relevanten Bereich, wie bei der Messung der CPU-Zeit. Messen Sie die Länge der Balken in der GPU-Hardwarewarteschlange mit der gleichen Farbe wie die Farbe der Kontext-CPU-Warteschlange. Solange die Balken in aufeinander folgende v-Synchronisierungen passen, wird die App bei 60FPS reibungslos ausgeführt.

    Screenshot, der ein Beispiel für die GPU-Hardware-Warteschlange zeigt, die Informationen darüber anzeigt, dass eine App mit 60 FPS läuft.

Berechnen der CPU- und GPU-Zeit beim Rendern von 8192 nicht realisierten Primitiven

  1. Wenn Sie die gleichen Schritte erneut ausführen, zeigt die Ablaufverfolgung an, dass die gesamte CPU-Arbeit für einen Frame nicht zwischen einer v-Synchronisierung und der nächsten passt. Dies bedeutet, dass die App CPU-gebunden ist. Der UI-Thread sättigt die CPU.

    Screenshot, der ein Beispiel zeigt, wie der UI-Thread die CPU auslastet.

    Beim Betrachten der Flip-Queue wird auch deutlich, dass DWM nicht jeden Frame präsentieren kann.

    Screenshot, der ein Beispiel für die Unfähigkeit von D W M zeigt, jeden Frame zu präsentieren.

  2. Um zu analysieren, wo die Zeit aufgewendet wird, öffnen Sie die Spur in XPerf. Um die Startzeit in XPerf zu analysieren, suchen Sie zuerst das Zeitintervall in GPUView. Fahren Sie mit der Maus über den linken und rechten Rand des Intervalls und notieren Sie sich die absolute Zeit, die unten im GPUView-Fenster angezeigt wird. Öffnen Sie dann die gleiche ETL-Datei in XPerf , scrollen Sie nach unten zum Diagramm "CPU Sampling by CPU", klicken Sie mit der rechten Maustaste, und wählen Sie "Intervall auswählen..." aus. Dies ermöglicht die Eingabe in das Intervall von Interesse, das durch die Betrachtung der GPU-Ablaufverfolgung ermittelt wurde.

    Ein Screenshot zeigt

  3. Wechseln Sie zum Menü "Trace", und stellen Sie sicher, dass "Symbole laden" markiert ist. Wechseln Sie auch zur Ablaufverfolgung> – Konfigurieren von Symbolpfaden, und geben Sie den App-Symbolpfad ein. Eine Symboldatei enthält Debuginformationen zu einer kompilierten ausführbaren Datei in einer separaten Datenbank (PDB). Diese Datei wird häufig als PDB bezeichnet. Weitere Informationen zu Symboldateien finden Sie hier: Symboldateien. Diese Datei kann sich im Ordner "Debug" des App-Verzeichnisses befinden.

  4. Um die Aufschlüsselung der In-App-Zeit zu erhalten, klicken Sie mit der rechten Maustaste auf das im vorherigen Schritt ausgewählte Intervall, und klicken Sie auf "Zusammenfassungstabelle". Um einen Überblick darüber zu erhalten, wie viel Zeit in jeder DLL aufgewendet wird, entfernen Sie das Häkchen bei „Stapel“ im Menü „Spalten“. Beachten Sie, dass die Spalte "Anzahl" hier zeigt, wie viele Beispiele innerhalb der angegebenen DLL/Funktion sind. Da ungefähr ein Beispiel pro Ms genommen wird, kann diese Zahl als beste Schätzung verwendet werden, um zu ermitteln, wie viel Zeit in jeder DLL/Funktion aufgewendet wird. Im Spaltenmenü das Aktivieren der Option 'Stapel' gibt die inklusive Zeit für jede Funktion im Funktionsaufrufdiagramm an. Dies wird dazu beitragen, die Problempunkte weiter aufzuschlüsseln.

  5. Stack-Trace-Informationen für 2048 unrealisierte Primitives zeigen, dass 30% der CPU-Zeit für den Geometrie-Realisation-Prozess aufgewendet wird. Davon werden rund 36% der Zeit für Geometrie-Tessellierung und Strichziehen aufgewendet.

  6. Stapelablaufverfolgungsinformationen für 8192 unrealisierte Grundtypen zeigen, dass etwa 60% der CPU-Zeit (4 Kerne) in der Geometrie-Realisierung aufgewendet wird.

    Screenshot, der die Stack-Trace-Informationen für die C P U-Zeit anzeigt.

CPU-Zeit berechnen, wenn 8192 Primitive gerendert und realisiert werden.

Aus den Profilen ist klar, dass die App CPU-gebunden ist. Um die von der CPU aufgewendete Zeit zu reduzieren, können Geometrien einmal erstellt und zwischengespeichert werden. Der zwischengespeicherte Inhalt kann in jedem Frame gerendert werden, ohne dass die Aufwände für die Geometrie-Tessellation pro Frame anfallen. Beim Betrachten der Ablaufverfolgung in GPUView für den realisierten Teil der App ist klar, dass DWM jeden Frame präsentieren kann und die CPU-Zeit drastisch reduziert wurde.

Screenshot, das ein Beispiel einer Ablaufverfolgung in GPUView zeigt, wobei D W M in der Lage ist, jedes Frame zu präsentieren.

Der erste Teil des Diagramms zeigt realisierte 8192-Grundtypen. Die entsprechende CPU-Zeit pro Frame kann in zwei aufeinander folgende v-Synchronisierungen passen. Im späteren Teil des Diagramms ist dies nicht wahr.

Wenn Sie in XPerf nachsehen, ist die CPU für längere Zeit im Leerlauf, wobei nur etwa 25% der CPU-Zeit auf die Geometrie-Realisation-App entfällt.

Gpuview-Screenshot.

Zusammenfassung

Sowohl GPUView als auch XPerf sind leistungsstarke Tools zur Analyse der Performance von DirectX-Apps. Dieser Artikel ist eine Einführung in die Verwendung dieser Tools sowie in grundlegende Leistungsmessungen und App-Eigenschaften. Neben dem Verständnis der Verwendung von Tools ist es zunächst wichtig, die analysierte App zu verstehen. Beginnen Sie mit der Suche nach Antworten auf Fragen wie dem, was die App zu erreichen versucht? Welche Threads im System sind am wichtigsten? Welche Kompromisse sind Sie bereit zu machen? Beginnen Sie beim Analysieren von Leistungsspuren, indem Sie offensichtlich problematische Bereiche betrachten. Ist die App CPU oder GPU gebunden? Kann die App jeden Frame präsentieren? Tools können zusammen mit einem Verständnis der App sehr nützliche Informationen beim Verständnis, beim Auffinden und letztendlich beim Lösen von Leistungsproblemen liefern.