Unity UI Profiling: Wer verdirbt meine Stapelverarbeitung?


Sie haben unendlich viel Zeit damit verbracht, die Unity-Benutzeroberfläche zu optimieren. Um jedoch eine Hemmung zu verursachen, reicht eine kleine Änderung des winzigen Attributs des fast unsichtbaren UI-Canvas-Elements aus. In diesem Fall können Sie selbst durch die Profilerstellung für die Unity-Benutzeroberfläche nicht die FPS senken. Bist du bereit für eine lange Fehlerbehebung?

Genau das ist in meinem letzten Projekt passiert ...

Ich habe hart gearbeitet, um mehrere UI-Panels im Port unseres Spiels auf Oculus Quest zu optimieren. Grundsätzlich bestand die Aufgabe darin, das Überziehungsniveau auf akzeptable Werte zu reduzieren, damit die GPU das Wichtigste bewältigen kann - echtes 3D-Rendering.

Also habe ich mindestens einen Monat lang an der Optimierung der Unity-Benutzeroberfläche gearbeitet und schließlich verdammt gute Fortschritte gemacht.

Irgendwann wurde die Benutzeroberfläche so optimiert, dass sie die GPU-Timings kaum beeinflusste. Die von mir implementierten Dimmtechniken der undurchsichtigen Benutzeroberfläche kompensierten die meisten Neuzeichnungen, die durch das Überlagern der Benutzeroberfläche (über andere Elemente gezeichnete Elemente) verursacht wurden.

Also habe ich ein hochoptimiertes Hybrid-UI-System erhalten, das die darunter gezeichneten 3D-Elemente im Wesentlichen überlappte. Es ist sehr einfach geworden, das Rendern dieser überlappenden Fragmente zu verwerfen.

Die Arbeiten waren jedoch noch lange nicht abgeschlossen ...

Als ich den Unity UI Profiler einsteckte, fiel mir eines auf.

Ich habe gesehen, dass eine überlastete CPU mehr als 1 ms in jedem Frame für das Rendern der Benutzeroberfläche benötigt. Dies ist viel Zeit für eine Plattform, die Ihnen ein Budget von 13 ms für das gesamte Spiel bietet: Physik, Logik, 3D-Rendering, Eingabe, VR und Netzwerkcode.

Und schließlich gab es Fälle, in denen die Benutzeroberfläche die CPU-Leistung noch mehr „beeinträchtigte“.


Unity-Benutzeroberfläche: Kostspielige Build-Batches

Und dies sagt eines aus: Die Benutzeroberfläche kann für die GPU optimiert werden, dies bedeutet jedoch nicht unbedingt eine Optimierung für die CPU .

Tatsächlich sind beim Rendern der Unity-Benutzeroberfläche die CPU- und GPU-Aufgaben sehr unterschiedlich. Es überrascht nicht, dass ich empfehle, die CPU- und GPU-Optimierung unterschiedlich anzugehen. Dies wurde in meinem vorherigen Beitrag zur Optimierung der Unity-Benutzeroberfläche erläutert.

Eine weitere Profilerstellung der Unity-Benutzeroberfläche ergab ein offensichtliches Problem: Die Benutzeroberfläche wurde in jedem neuen Frame ständig neu erstellt, d. H. Canvas (Canvas Rebuild) wurde in jedem Frame neu erstellt .

Konstante Belastung der CPU für 1 ms ... oh-oh.

Aber warum tut mir Unity das an? Ich dachte, Unity speichert alle Canvas-Schnittstellen zwischen ...

Eigentlich ja. Unity speichert Canvas effektiv zwischen, sodass sie nur einmal gesammelt werden.

Das Problem tritt jedoch auf, wenn Sie die Eigenschaften eines der UI-Elemente im Canvas-Bereich ändern - Farbe, Position usw.

Das heißt, all die Animationen, die wir lieben, zum Beispiel die Auswirkungen von Schaltflächen, wenn Sie schweben, die Produktivität beeinträchtigen, und das wissen Sie wahrscheinlich nicht.

Wenn eine Änderung der UI-Eigenschaften auftritt, führt Unity den berühmten Canvas Rebuild aus, der die Leistung des Spiels beeinträchtigt .

Die Canvas-Neuerstellung der Benutzeroberfläche zwingt die Unity-Engine, alle UI-Elemente dieses Canvas iterativ zu durchlaufen, um eine optimierte Liste von Zeichenaufrufen (viele Scheitelpunkte, Farben, Materialien usw.) zu generieren. Und der Canvas Rebuild dauert länger als der Seat Panda , um von null auf 60 Meilen pro Stunde zu beschleunigen.

Angesichts der Tatsache, dass wir ständig unter Canvas Rebuild leiden, wäre es logisch, eine Frage zu stellen ...

Warum leiden wir unter Canvas Rebuilds und was kann man dagegen tun?

Um diese einfache Frage zu beantworten, musste ich mehr als 5 Stunden damit verbringen, das Thema zu studieren und mit dem Unity UI Profiler zu arbeiten .

Lass es uns richtig machen.

1. Profiling Unity UI: Im Moment ist alles in Ordnung ...


Stellen Sie sich vor, wir haben eine einfache Benutzeroberfläche.

Diese Benutzeroberfläche macht nichts, sie erscheint nur auf dem Bildschirm und nervt den Spieler, der versucht, etwas durch sie hindurch zu sehen.

Bei mehr als 350 Bildern in der Rasterlayoutgruppe sieht es folgendermaßen aus:


Beispiel für die Profilerstellung für die Unity-Benutzeroberfläche

Und trotz mehr als 350 Bildern ist alles in Ordnung. Im Standardfall wird die Benutzeroberfläche in nur zwei Zeichenaufrufen gerendert, da nur zwei eindeutige Bilder darin enthalten sind, die nicht im Sprite-Atlas enthalten sind.

Tatsächlich kann ich im Profiler sehen, dass die CPU praktisch nicht belastet ist. Die meiste Zeit, die auf der Benutzeroberfläche verbracht wird, beträgt weniger als 0,01 ms , was verdammt gut ist.


Unity UI Profiling: Ein mysteriöser Anstieg

(... die meiste Zeit)

Warten Sie, woher kam dieser Anstieg der CPU-Ressourcen am Ende des Diagramms?

2. Unity UI Profiling: Plötzlicher Canvas-Neuaufbau!


Was ist am Ende des Einheitsprofils passiert? Sehr seltsam, in nur einer Sekunde war der CPU-Overhead auf der Unity-Benutzeroberfläche mehr als doppelt so hoch.

Ich möchte ein Spiel spielen

Finden Sie die beiden Unterschiede in den folgenden Beispielen (möglicherweise müssen Sie die Bilder in einem separaten Fenster öffnen, um besser sehen zu können) .


Unity UI Profiling: Kostengünstiges Canvas


Unity UI Profiling: Canvas Rebuild

Ich gebe Ihnen fünf Sekunden, um es herauszufinden.

5, 4 ... nun, hier ist ein Tipp, um die Aufgabe zu vereinfachen:


Profilerstellung für die Unity-Benutzeroberfläche: Overhead Canvas Rebuild

Wow!

PostLateUpdate.UpdateRectTransform und UGUI.Rendering.UpdateBatches möchten unbedingt die Hauptstars dieser Show werden.

Was machen diese Bereiche?

Das erste, UpdateRectTransform , macht deutlich, dass sich die Transformation eines Objekts geändert hat und Unity daher teure Logik ausführen muss, um visuelle Änderungen widerzuspiegeln. Wir wissen nicht, ob es sich um eine Position, Drehung, Skalierung oder eine andere Eigenschaft von RectTransform .

Zur Hölle, wir wissen nicht einmal, ob es nur ein Attribut war oder alles auf einmal. War es ein einzelnes Objekt oder mehrere? Und welche? Das ist das Problem: Wir wissen es nicht .

Das zweite teure Stück, UpdateBatches , bezieht sich auf die Notwendigkeit, die gesamte Canvas-Geometrie neu zu UpdateBatches . Dieser Vorgang wird als Canvas Rebuild bezeichnet . Das Neuerstellen von Canvas bedeutet, dass Unity die gesamte Canvas-Hierarchie umgeht, um eine Liste von Zeichnungsaufrufen zu generieren. Die Eckpunkte, Indizes, Farben und UV-Werte aller Elemente werden berechnet. Anschließend wird der Batch-Durchlauf durchgeführt, um die maximal mögliche Anzahl von Zeichenaufrufen zu kombinieren und die übermäßige Belastung der CPU zu verringern, die diese an den Grafiktreiber überträgt.

Jetzt scheinen wir zu wissen, was passiert und sind auf dem richtigen Weg. Aber wie vermeide ich diese Überholung der Leinwand? Was verursacht sie?

Wir brauchen genauere Informationen ...

Zusammenfassend

  • Durch Ändern eines Attributs in einem UI-Element wird das Element selbst als fehlerhaft markiert
  • Das UI-Element kann vollständig verschmutzt sein, aber auch teilweise: verschmutzte Oberteile, verschmutztes Layout, verschmutzte Materialien. Es ist einfacher, sich von teilweise verschmutzten Zuständen zu erholen
  • Sobald Canvas-Elemente als fehlerhaft markiert sind, wird sie von Unity vollständig neu erstellt
  • Canvas-Neuaufbauten sind für die CPU teuer, daher ist es am wichtigsten, sie zu vermeiden

3. Auf der Suche nach einem Schädling: eine politisch inkorrekte Art der rohen Gewalt


Wir müssen noch die folgende Frage beantworten:

Was verursacht diesen Canvas Rebuild?

Es stellt sich heraus, dass es keinen schnellen Weg gibt, dies herauszufinden, insbesondere bei einer großen Canvas-Hierarchie.

Aber zuerst zeige ich Ihnen eine Brute-Force-Methode, um den Grund für Canvas Rebuild zu finden .


1. Lassen Sie Unity UI Profiler die Aufzeichnung fortsetzen

Wir werden die Metriken herausfiltern, damit wir uns auf das Wichtigste konzentrieren können: Rendering, Skripte und Benutzeroberfläche.

Verfolgen Sie die anfängliche Markierung, um die Kosten des aktuellen Schemas zu verstehen, einschließlich des kostspieligen Canvas-Wiederaufbaus.


2. Deaktivieren Sie Spielobjekte auf der Benutzeroberfläche und vergleichen Sie die Messwerte

Wählen Sie die Spielobjektgruppe aus und deaktivieren Sie sie.

Vergleichen Sie die Leistungsmetriken.

Wenn sich die Messwerte nicht wesentlich verbessert haben, deaktivieren Sie die Spielobjekte weiterhin, bis Sie eine signifikante Verbesserung feststellen.


3. Finden Sie heraus, was seine Eigenschaften ändert

Wir konnten das Objekt auswählen, das den Canvas Rebuild aufruft. Aber was genau wird ihre Ursache?

Vielleicht ändert sich seine Größe durch das Skript? Oder ändert sich seine Position durch Animation?

Klicken Sie mit der rechten Maustaste auf RectTransform und wählen Sie " Referenzen in Szene suchen ".

Wenn Sie herausfinden, was die Neuerstellung von Canvas verursacht, tun Sie etwas dagegen, indem Sie beispielsweise Animationen oder Transformationen deaktivieren.

Ruben, aber wie verwende ich diese Methode mit einer riesigen Hierarchie der Benutzeroberfläche? Sag mir keinen Bullshit

Ich sagte, dass der Prozess weder schnell noch interessant sein wird, aber die Spieler werden Ihnen dankbar sein.

Das ist der Punkt. Erstens ist die Existenz einer riesigen Hierarchie keine ideale Situation. Es sind so massive und tiefe Hierarchien, die Canvas Rebuild für die CPU so teuer machen.

Es können (und werden) jedoch große und verschachtelte UI-Hierarchien entstehen. Erwarten Sie daher, dass die Canvas-Neuerstellung das Wichtigste trifft: das Gameplay.

Obwohl die Brute-Force-Methode dabei hilft, die Quelle der Canvas-Überholung zu finden, lässt sie sich auf lange Sicht nicht gut skalieren.

Nachdem ich die Benutzeroberfläche professioneller optimiert habe, habe ich ein Tool erstellt, das alle Antworten liefert, die ich brauche, damit das Projekt die Erwartungen der Spieler erfüllt ...


Profiling Canvas Rebuild

4. Bonus: Verbesserung der Optimierungsfunktionen der Unity Profiler-Benutzeroberfläche


Ich hoffe, Sie verstehen bereits, wie häufig und störend Canvas Rebuild sein kann.

Diese Perestroika, die mein Spiel infiziert hat, hat bis zu 10% des gesamten CPU-Budgets gekostet!

Wie wir gesehen haben, gibt es eine Brute-Force-Methode zum Auffinden von Canvas Rebuild-Quellen. Vielleicht können Sie mit den in meinem Beitrag aufgeführten Strategien zur Optimierung der Unity-Benutzeroberfläche umgehen.

Aber solch ein fehleranfälliger Prozess würde niemals einen echten Guru befriedigen. Sie können mehrere Tage mit Canvas Rebuild verbringen, aber im unerwartetsten Moment verschwinden sie wieder, sobald Sie den Unity UI Profiler anschließen.

Wenn Sie ein Spiel für VR entwickeln, wird dies kritisch. Wir möchten nicht, dass Canvas in der Benutzeroberfläche des Weltraums neu erstellt wird. Wenn Sie die Perestroika nicht loswerden können, werden Ihre Spieler es höchstwahrscheinlich nicht aushalten.

Okay, ich habe die Idee, Canvas Rebuilds loszuwerden. Unity Profiler bietet jedoch fast keine Informationen dazu! Was können Sie raten?

Ich bin froh, dass du gefragt hast. Es stellt sich heraus, dass wir Unity Profiler davon überzeugen können, uns nützliche Informationen darüber zu liefern, was die Leistung der Benutzeroberfläche beeinträchtigt .

Wir können die Funktionalität von Unity UI Profiler erweitern . Dazu müssen Sie den öffentlich verfügbaren Quellcode der Unity-Benutzeroberfläche ändern. Sobald Sie den Quellcode erreicht haben, müssen Sie die Codefunktionen finden, in denen die Canvas-Neuerstellungen stattfinden . Dann brauchen wir API-Magie mit BeginSample und EndSample Profiler .

Wenn Sie Unity 2019.1 oder früher ausführen, befindet sich der Quellcode für die Unity-Benutzeroberfläche im Bitbucket-Repository . Es gibt auch eine Anleitung zum Herunterladen, Installieren und Ändern.

Was rate ich? Verwenden Sie eine neuere Version von Unity, die nicht niedriger als 2019.2.0 ist. Neuere Versionen von Unity werden standardmäßig mit der Quell- Benutzeroberfläche geliefert, da das Benutzeroberflächensystem jetzt Teil des Paketmanagers ist. Dies ist der problemloseste Weg.

Hier ist eine Liste von Codeteilen, die ich während meiner Recherche entdeckt habe und in denen ich Profiling-API-Aufrufe hinzufügen kann:



Unity-Benutzeroberfläche: Profilierungsquelle

Ist es hilfreich? Ja

Praktisch für den Künstler / Designer? Nein.

Es war der Dichter, der die kleine Open-Source- Unity-Erweiterung geschrieben hat , die die Funktionen des Unity-Profilers erweitert .


Mit diesem kostenlosen Tool können wir schnell zwischen verschiedenen Profilierungsmodi wechseln, um maximale Spielleistung zu gewährleisten.

Was ist das Beste an diesem Unity Profiler-Expander? Es funktioniert außerhalb des Editors und entlastet Sie im Wesentlichen von allen Kopfschmerzen bei der Profilerstellung der Benutzeroberfläche für Android und andere Plattformen.

Hier ist es, seine gesamte Leistung wird mit nur zwei Tasten gesteuert:

  • Buff mein Unity Profiler
  • Nerf mein Unity Profiler .

Sie können dieses Tool hier erhalten .

Source: https://habr.com/ru/post/de472854/


All Articles