Rendering-Optimierung für Mobile, Teil 2. Die Hauptfamilien moderner mobiler GPUs

Grüße, liebe Liebhaber und Profis, Grafikprogrammierer! Beginnen wir mit dem zweiten Teil unserer Artikelserie über die Renderoptimierung für Mobilgeräte. In diesem Teil werden wir die Hauptfamilien von GPUs betrachten, die von Spielern auf Mobilgeräten vorgestellt werden.


Berücksichtigen Sie zunächst eine Reihe von Kriterien, anhand derer mobile GPUs klassifiziert werden können.

Einheitliche oder spezialisierte Shader-Kernel


In der Ära der frühen mobilen Grafikkarten, bevor sich komplexe Effekte ausbreiteten, gab es einen Standpunkt, dass für Fragment-Shader die Unterstützung von Berechnungen mit reduzierter Genauigkeit ausreichend ist. In einem typischen Anzeigemodus werden tatsächlich 8 oder sogar weniger Bits für jeden Farbkanal verwendet. Diese Ansicht hat zur Verwendung spezialisierter Shader-Kerne geführt. Für die Eckpunkte verwendeten wir Kernel, die für Matrixtransformationen mit erhöhter Genauigkeit FP24 / FP32 ( Highp ) optimiert wurden . Für Pixel Kerne, die mit reduzierter Genauigkeit effizienter arbeiten FP16 ( Mediump ). Mit diesem HighpSie wurden nicht unterstützt. Diese Spezialisierung ermöglicht es uns auf den ersten Blick, eine rationellere Verteilung der Transistoren auf dem Chip zu erreichen. In der Praxis führt dies jedoch zu Schwierigkeiten bei der Entwicklung komplexer Effekte sowie bei der Verwendung hochauflösender Texturen. Darüber hinaus kann eine Kernspezialisierung zu einem Vertex / Fragment-Engpass führen . Dieser Begriff bezieht sich auf die Situation, in der aufgrund der asymmetrischen Belastung der Scheitelpunkt- und Pixelkerne einige der Kerne „inaktiv“ waren. 


Moderne Architekturen verwenden daher einheitliche Kerne. Solche Kernel können abhängig von der Last Scheitelpunkt-, Pixel- und andere Rechenaufgaben übernehmen.


Vektor (SIMD) oder skalarer Befehlssatz


Im Geiste des oben beschriebenen Wunsches, Transistoren einzusparen, die auf Kerne spezialisiert sind, wurde ein Satz von Shader-Anweisungen entworfen. Die meisten typischen Transformationen für dreidimensionale Grafiken arbeiten mit 4 Komponentenvektoren. Daher arbeiteten frühe GPUs speziell mit solchen Operanden. Wenn der Shader-Code heterogene Skalaroperationen enthielt, die vom Optimierer nicht in Vektoroperationen gepackt werden konnten, wurde ein Teil der Rechenleistung nicht verwendet. Dieses Phänomen kann wie folgt dargestellt werden:


Es gibt einen Shader, der die allgemeine Operation "Multiplizieren" implementiert: Multiplizieren Sie 2 Operanden und fügen Sie dann den dritten hinzu. Beim Kompilieren auf einer bedingten Vektorarchitektur (Vector ISA = Vector Instruction Set Architecture) erhalten wir einen Vektorbefehl vMADD , der für 1 Takt ausgeführt wird. Bei einer bedingten Skalararchitektur erhalten wir 4 Skalarbefehle, die dank einer verbesserten Pipeline auch in einem Taktzyklus ausgeführt werden. Stellen Sie sich nun einen ausgeklügelten Shader vor, der zwei Operationen ausführt, jedoch zwei Operanden.


Bei der Vektorarchitektur erhalten wir bereits 2 Befehle, für deren Ausführung 2 Taktzyklen erforderlich sind. Es werden jedoch keine Maßnahmen für die .zw- Komponenten ergriffen , und die Verarbeitungsleistung ist im Leerlauf. Im Fall einer skalaren Architektur können dieselben Operationen in 4 skalaren sMADDs gepackt werden , die im selben 1-Takt-Zyklus ausgeführt werden. Somit wird bei einer skalaren Architektur aufgrund der Verbesserung der Pipeline eine höhere Berechnungsdichte erreicht. Wie unten gezeigt wird, ist der Vektor ISA jedoch immer noch relevant. Daher ist es sinnvoll, Vektorisierungstechniken für Shader-Code anzuwenden. Mit ihnen können Sie mit Vektor- ISA eine höhere Leistung auf Grafikkarten erzielen . Gleichzeitig beeinträchtigt dies in der Regel nicht die Leistung eines moderneren SkalarsDie ISA .

Basierend auf den oben genannten Merkmalen werden wir die Familien mobiler GPUs betrachten, die in unserer Zeit üblich sind. Beginnen wir mit der häufigsten Familie. Viele Leute wissen, dass es sich um Mali -Grafikkarten der britischen Firma ARM handelt . ARM ist nicht direkt an der Chipherstellung beteiligt und bietet stattdessen geistiges Eigentum an. Wie andere mobile Grafikkarten ist Mali Teil von System on Chip (SoC) , d. H. arbeitet mit gemeinsam genutzten Speicher für die CPU und GPU und Bus. 

Mali utgard


2008 wurden die ersten Vertreter der Mali-Utgard- Architektur geboren , die bis heute relevant sind. Diese Grafikkarten werden nach dem Mali-4-Schema xx MP n benannt , wobei xx die Modellnummer und n die Anzahl der Fragmentkerne ist. In Mali Utgard Shader Kernspezialität, und alle Modelle kommen mit einem Scheitelpunkt nur 1 Kern.

Weitere Merkmale der Mali Utgard-Architektur:

  • OpenGL ES 2.0 
  • Fehlende Highp- Unterstützung in fragmentierten Kerneln
  • Vektorbefehlssatz (es ist sinnvoll, Berechnungen zu vektorisieren)

Trotz der OpenGL ES- Spezifikation kompilieren Mali Utgard -Grafikkartentreiber erfolgreich Fragment-Shader, die hohe Präzision verwenden (z. B. wird die Genauigkeit standardmäßig mit präzisem Highp-Float festgelegt ). Aber die Genauigkeit von mediump wird tatsächlich verwendet . Daher ist es ratsam, zusätzlich alle Shader für Handyspiele auf solchen Grafikkarten zu testen. Nach Angaben von Unity arbeitete Mali Utgard Ende 2019 für etwa 10% der Spieler an Geräten. Und wenn Sie die entsprechenden Filter auf market.yandex.ru einstellen , können Sie sehen, dass 2019 mehr als 10 neue Telefone mit Grafikkarten dieser Architektur angekündigt wurden.


Wenn Sie bereit sind, diese Zielgruppe zu verlassen, reicht es aus, die Anforderungen für die OpenGL ES 3.0-Unterstützung in AndroidManifest.xml festzulegen:

<uses-feature android:glEsVersion="0x00030000" android:required="true"⁄>

Neben Mali Utgard gibt es derzeit keine weit verbreiteten mobilen GPUs ohne Unterstützung für OpenGL ES 3.0.

Besonders hervorzuheben ist die Verwendung hochauflösender Texturen auf dem Mali Utgard . Zehn Bits der Mantisse mit mittlerer Genauigkeit reichen für eine qualitativ hochwertige Texturierung mit einer Texturauflösung von mehr als 1024 auf einer Seite nicht aus. Obwohl in Mali Utgard- Fragmentkernen nur mittlere Genauigkeit unterstützt wird , können Sie die Genauigkeit der fp24- Texturkoordinaten erhalten, wenn Sie direkt variieren .

// vertex shader
varying highp vec2 v_texc;
void main()
{
    v_texc = …;
}

//  fragment shader
...
varying highp vec2 v_texc;
void main()
{
    gl_FragColor = texture2D(u_sampler, v_texc); //  v_texc 
                                                 //  
}

Als Bonus für einige Architekturen können Sie mit diesem Ansatz Texturinhalte vorab abrufen, bevor Sie einen Fragment-Shader ausführen. Dadurch werden Verzögerungen minimiert, während Sie auf Ergebnisse der Texturabtastung warten.

Mali Midgard


Das Mali Utgard wurde durch die Mali Midgard Architektur ersetzt . Es gibt mehrere Generationen dieser Architektur mit den Namen der Arten Mali-6xx , Mali-7xx und Mali-8xx . Trotz des 8-jährigen Alters kann Mali Midgard als moderne Architektur bezeichnet werden, die die meisten neuen Funktionen unterstützt:

  • Unified Shader-Kernel
  • OpenGL ES 3.2 (Compute & Geometry Shader, Tesselation ...)

Der Mali Midgard behält jedoch den Vektor ISA bei . Angesichts der weit verbreiteten Verwendung von Mali Midgard (etwa 25% unseres Publikums) ist eine Vektorisierung des Computing angemessen.

Ein weiteres Merkmal von Mali Midgard ist die Forward Pixel Kill- Technologie . Jedes Pixel wird in einem separaten Strom des Fragmentkerns berechnet. Wenn während der Ausführung des Streams bekannt wird, dass das resultierende Pixel durch ein undurchsichtiges Pixel eines anderen Grundelements blockiert wird, wird der Stream vorzeitig beendet und die freigegebenen Ressourcen werden für andere Berechnungen verwendet.

Mali Bifrost


Neben Midgard zeichnet sich die Bifrost- Architektur durch den Übergang zur skalaren ISA aus . Im Vergleich zur vorherigen Architektur wurde die maximale Anzahl von Kernen erhöht (von 16 auf 32) und eine verbesserte Schnittstelle mit einer CPU unterstützt, die einen kohärenten Zugriff auf den gemeinsam genutzten Speicher ermöglicht: Änderungen am Inhalt des CPU- / GPU-Speichers werden trotz der Caches sofort für einander "sichtbar" ermöglicht es Ihnen, die Synchronisation zu vereinfachen.

Von inoffiziell


Es wurden viele Versuche unternommen, Mali -Grafikkarten zurückzuentwickeln , um Open Source- Treiber für Linux zu erstellen . Die Arbeiten der engagierten Menschen, die dies versuchen, ermöglichen es uns, einen Blick auf die undokumentierten Funktionen von Mali -Grafikkarten zu werfen . Im PanFrost- Projekt gibt es also einen Disassembler für Mali Midgard / Bifrost , mit dem Sie sich mit einer Reihe von Shader-Anweisungen vertraut machen können (es gibt keine offenen offiziellen Informationen zu diesem Thema).


Adreno


Die zweithäufigste Familie mobiler GPUs ist Adreno . Diese Grafikkarte wird auf dem SoC installiert , der unter der Marke Snapdragon der amerikanischen Firma Qualcomm bekannt ist . Snapdragon ist in den Top-End-Smartphones unserer Zeit von Samsung , Sony und anderen installiert . Die

aktuellen Adreno -Grafikkarten sind Familien der Serien 3xx - 6xx. Alle diese Serien kombinieren die folgenden Merkmale:

  • Unified Shader-Kernel
  • Pseudo-TBR (große Kachelgrößen in einem herkömmlichen dedizierten GPU-Speicher)
  • Automatisches Umschalten im Sofortmodus Rendern je nach Art der Szene ( FlexRender )
  • Skalarbefehlssatz

Ab Adreno 4xx wird die Unterstützung für OpenGL ES 3.1 und für Adreno 5xx - Vulkan und OpenGL ES 3.2 eingeführt .

Auf Adreno-Kacheln basierendes Rendering


Adreno-Grafikkarten haben eine „traditionelle“ GPU namens GMEM . Es gelten Volumes von 128 KB bis 1536 KB. Auf diese Weise können Sie im Vergleich zu Architekturen anderer Entwickler mobiler GPUs eine größere Kachelgröße verwenden. Bei Adreno ist die Größe der Kacheln dynamisch und hängt vom verwendeten Farbformat, dem Tiefenpuffer und der Schablone ab. Wenn Sie im Sofortmodus arbeiten, erfolgt das Rendern im Systemspeicher. Es gibt eine GL ES-Erweiterung, mit der Sie den bevorzugten Modus angeben können: QCOM_binning_control . Die neuesten Empfehlungen von Qualcomm empfehlen jedoch, sich ausschließlich auf GPU-Treiber zu verlassen, die selbst den am meisten bevorzugten Modus für den von der Anwendung generierten Befehlspuffer bestimmen. 

Wenn Sie im TBR- Modus arbeiten Adreno macht 2 Vertex-Pässe:

  1. Binning-Pass - Verteilung der Grundelemente nach Bin ( Bins , ein Synonym für Kacheln)
  2. Vollständiger Scheitelpunktdurchlauf zum Rendern nur der Grundelemente, die in den aktuellen Bin fallen

Während des Binning-Durchgangs berechnet Adreno nur die Scheitelpunktpositionen. Andere Attribute werden nicht berechnet und unnötiger Code wird vom Optimierer entfernt. In der offiziellen Dokumentation (9.2 Scheitelpunktverarbeitung optimieren) wird empfohlen, die zur Berechnung der Positionen erforderlichen Scheitelpunktinformationen getrennt von den übrigen Daten zu speichern. Dies macht das Zwischenspeichern von Scheitelpunktdaten effizienter.

Freedreno


Im Gegensatz zu ARM und Imagination Technologies zögert Qualcomm, die Details der internen Struktur seiner GPUs mitzuteilen. Dank der Bemühungen des Reverse Engineers Rob Clark kann jedoch viel aus dem Freedreno- Projekt , dem Open-Source- Adreno- Treiber für Linux , gelernt werden .

Rob Clark von Freedreno

PowerVR von Imagination Technologies


Imagination Technologies ist ein britisches Fabless-Unternehmen, das für die Entwicklung von GPUs für Apple-Produkte bekannt ist. Das Unternehmen übte diese Rolle bis zum Aufkommen des iPhone 8 / X aus, das die interne Entwicklung von Apple nutzt. Obwohl die Empfehlungen zu Optimierungen für diese Chips, die unverändert geblieben sind, sowie Patentansprüche gegen Apple von Imagination darauf hindeuten, dass Apple die PowerVR-Architektur weiterentwickelt hat, eine ursprüngliche Entwicklung von Imagination. Zu Beginn des Jahres 2020 von Apple zurückkehrte , um die Lizenzierung Praktiken mit Imagination Technologies. Neben Geräten mit iOS / iPadOS sind PowerVR-Grafikkarten in einer Vielzahl von Android-Smartphones und -Tablets installiert.


Betrachten Sie die Familie der PowerVR-Grafikkarten, die immer noch unter den Benutzern zu finden sind.

PowerVR SGX


Die ersten PowerVR SGX-Grafikkarten wurden 2009 veröffentlicht. Es gibt mehrere Generationen dieser Architektur: Series5, Series5XT und Series5XE. Apple hat diese GPUs bis zum iPAD 4 / iPhone 5 / iPOD Touch 5 verwendet. Die folgenden SGX-Funktionen können angeführt werden:

  • Unified Shader-Kernel
  • OpenGL ES 2.0
  • Vektorbefehlssatz
  • Unterstützung für 10-Bit-Lowp-Präzision in Shadern
  • geringe Leistung von abhängigen Texturlesungen

Lassen Sie uns einige davon genauer betrachten. 

Geringe Genauigkeit


PowerVR SGX sind die einzigen aktuellen mobilen GPUs mit
Lowp- Hardware-Unterstützung . Neuere PowerVR-Modelle sowie alle modernen GPUs anderer Hersteller verwenden tatsächlich eine mittlere Genauigkeit . Durch die Verwendung von
Lowp beim PowerVR SXG können Sie eine höhere Berechnungsdichte erzielen (mehr Operationen pro Zyklus). Gleichzeitig ist die Swizzle-Operation (Permutation der Vektorkomponenten) für Lowp im Gegensatz zu anderen Präzisionen nicht frei. Diese Funktion sowie der enge Wertebereich, den lowp bietet ([-2,2]), schränken seinen Umfang ein. Gleichzeitig ist der schlecht eingestellte TiefpunktDies führt zu Artefakten in der SGX-Familie und wird nicht auf allen anderen Grafikkarten angezeigt, auf denen tatsächlich eine mittlere Genauigkeit verwendet wird . Aus diesem Grund sollten Sie in Betracht ziehen, die Verwendung von Lowp in Shadern zu verweigern .

Abhängige Textur liest


Wie Sie wissen, sind Texturabtastvorgänge am langsamsten, da auf die Leseergebnisse des Speichers gewartet werden muss. Im Fall von mobilem SoC handelt es sich um gemeinsam genutzten Systemspeicher mit einer CPU. Um die Anzahl der Zugriffe auf langsamen Speicher zu verringern, werden Textur-Caches verwendet. Um Ausfallzeiten zu Beginn der Rasterung mithilfe einer Textur zu vermeiden, ist es sinnvoll, die verwendeten Bereiche im Voraus zwischenzuspeichern. Wenn der Fragment-Shader die vom Vertex-Shader übergebene Texturkoordinate ohne Änderungen verwendet, kann der für das Caching erforderliche Texturabschnitt bestimmt werden, bevor der Fragment-Shader ausgeführt wird. Wenn der Fragment-Shader die Texturkoordinate ändert oder sie anhand von Daten aus einer anderen Textur berechnet, ist dies nicht immer möglich. Infolgedessen kann die Ausführung des Fragment-Shaders verlangsamt werden.PowerVR SGX-Grafikkarten sind in diesem Szenario besonders schmerzhaft. Darüber hinaus führt auch die Verwendung einer Permutation der Komponenten der Texturkoordinate (Swizzle) dazuabhängige Textur gelesen . Hier ist ein Beispiel für ein Shader-Programm ohne abhängiges Lesen der Textur .

Scheitelpunktprogramm

attribute highp vec2 a_texc;
varying highp vec2 v_texc;

void main()
{
	gl_Position = …
	v_texc = a_texc;
}


Fragmentprogramm

precision mediump float;
uniform sampler u_sampler;
varying highp vec2 v_texc;

void main()
{
	gl_FragColor = texture2D( u_sampler, v_texc ); //  dependent texture read
}

In diesem Fall:

Fragmentprogramm

precision mediump float;
uniform sampler u_sampler;
varying highp vec2 v_texc;

void main()
{
	gl_FragColor = texture2D( u_sampler, v_texc.yx ); // dependent texture read!
}

PowerVR Rogue


PowerVR-Grafikkarten wurden in der Rogue- Architektur weiterentwickelt . Es gibt mehrere Generationen dieser Architektur: von Serie 6 bis Serie 9. Alle PowerVR Rogue verfügen über folgende Funktionen:

  • Unified Shader-Kernel
  • skalare Befehlsarchitektur
  • Unterstützung für OpenGL ES 3.0+ (bis zu 3.2 sowie die Vulkan-API für neue Lineale) 

PowerVR TBDR


Wie alle gängigen mobilen GPUs verwendet PowerVR eine Kachel-Pipeline. Im Gegensatz zu Wettbewerbern ging Imagination jedoch noch einen Schritt weiter und implementierte eine verzögerte Rasterung von Grundelementen, sodass unsichtbare Pixelschattierungen unabhängig von der Renderreihenfolge übersprungen werden konnten. Dieser Ansatz wird als Tile Based Deferred Rendering bezeichnet , und der Prozess zum Eliminieren unsichtbarer Pixel wird als Hidden Surface Removal (HSR) bezeichnet.


Entfernen versteckter Oberflächen

Es wird empfohlen, undurchsichtige Geometrie transparent zu zeichnen und nicht Z Prepass zu verwenden. Dies führt bei PowerVR-Grafikkarten in den meisten Szenarien zu unnötiger Arbeit. Mehrere aufeinanderfolgende transparente Pixel, die sich überlappen, sind jedoch vollständig schattiert, um unter Berücksichtigung des Mischens die richtige Farbe zu erhalten. Das letzte transparente Pixel kann verworfen werden, wenn auf ein undurchsichtiges Pixel folgt. 

Offenheit Imagination Technologies


Die Entwickler von PowerVR haben mehr Open-Access-Dokumentation bereitgestellt als andere GPU-Entwickler. Die Architektur der Grafikpipeline sowie eine Reihe von Anweisungen für die Rogue-Architektur werden ausführlich beschrieben . Es gibt ein praktisches Tool PVRShaderEditor , mit dem Sie sofort Profilinformationen zum Shader sowie dessen zerlegte Liste für Rogue erhalten können.


Trotz der begrenzten Präsenz von PowerVR-Grafikkarten in der Umgebung von Geräten, die auf Android basieren, ist es sinnvoll, deren Architektur für die kompetente Programmierung von Grafiken für iOS zu untersuchen.

Mobile GPUs im Sofortmodus


Wir haben die häufigsten Familien mobiler Grafikkarten untersucht. Alle diese Familien verwendeten eine Kachel-Rendering-Architektur. Es gibt jedoch mobile Grafikkarten, die den traditionellen Sofortmodus- Ansatz verwenden. Hier sind einige davon:

  • nVIdia (Tegra SoC)
  • Alle Intel-Familien mit Ausnahme der neuesten Gen 11
  • Vivante GCxxxx (+ Arcturus GC8000)

Ein Merkmal von mobilen Grafikkarten, die im Sofortmodus arbeiten, ist der teure FBO-Reinigungsvorgang. Denken Sie daran, dass in der Kachelarchitektur die Vollbildbereinigung das Rendern beschleunigt, sodass der Treiber den Ladevorgang des alten Inhalts nicht zum Kachelspeicher hinzufügen kann. Bei mobilen GPUs im Sofortmodus ist die Vollbildbereinigung ein zeitaufwändiger Vorgang, mit dem solche GPUs unter anderem „berechnen“ können. Wenn das Hinzufügen einer Bereinigung nicht beschleunigt, sondern das Rendern verlangsamt, arbeiten wir höchstwahrscheinlich mit einer GPU im Sofortmodus . Vergessen wir natürlich nicht zu erwähnen, dass das Ändern eines Ziels bei GPUs im Sofortmodus ein „bedingt freies“ Verfahren ist.

Verteilung verschiedener Familien mobiler GPUs auf unsere Player


Hier sind die Statistiken zu mobilen GPUs, die Ende 2019 von unseren Spielern gesammelt wurden:


Nachfolgend öffnen wir das Segment „Sonstige“


Basierend auf diesen Daten betrachten wir die Verteilung der GPU hinsichtlich ihrer Hauptmerkmale.


Vektor-ALUs (arithmetische Logikeinheit) sind veraltet und werden durch skalare ersetzt. Heutzutage ist der Großteil der mobilen GPUs mit einem Vektorbefehlssatz der Mali Midgard , der als durchschnittlich in der Leistung angesehen werden kann. weil Die Vektorisierung verlangsamt in der Regel die Ausführung auf skalaren ALUs nicht. Es lohnt sich, die Vektorisierung als eine tatsächliche Technik zur Optimierung von Shadern für Mobilgeräte zu betrachten. 

Spezialisierte Shader-Kernel sind veraltet und werden durch einheitliche ersetzt. Der Vertex-Engpass am Skelettnetz ist nicht mehr beängstigend. Spezialisierte Kernel werden nur für die Mali-4xx (Utgard) -Familie verwendet . Denken Sie daran, dass diese GPUs nur OpenGL ES 2.0 unterstützen . Unser Publikum hat ungefähr 3,5% von ihnen.

Schließlich verwendet die überwiegende Mehrheit der mobilen GPUs den Kachelansatz. Der Sofortmodus ist marginalisiert und wird zusammen mit den Grafikkarten, die ihn verwenden, schnell herausgedrückt. Der Anteil der GPUs im Sofortmodus an unseren Playern beträgt ca. 0,7%.

Nützliche Links:


Vielen Dank für Ihre Aufmerksamkeit! Im nächsten Artikel aus der Reihe werden wir Techniken zur Optimierung von Shadern für Mobile betrachten.

All Articles