Optimalisasi rendering untuk Seluler, bagian 2. Keluarga utama GPU seluler modern

Salam, para pecinta dan profesional, programmer grafis! Mari kita mulai bagian kedua dari seri artikel kami tentang rendering optimisasi untuk Mobile. Pada bagian ini, kami akan mempertimbangkan keluarga utama GPU yang disajikan oleh pemain di Seluler.


Untuk memulai, pertimbangkan sejumlah kriteria di mana GPU seluler dapat diklasifikasikan.

Kernel shader bersatu atau khusus


Di era kartu video mobile awal, sebelum penyebaran efek kompleks, ada sudut pandang bahwa untuk shader fragmen, dukungan untuk perhitungan dengan akurasi berkurang sudah cukup. Memang, dalam mode tampilan khas, 8 atau bahkan lebih sedikit bit digunakan untuk setiap saluran warna. Pandangan ini telah menyebabkan penggunaan inti shader khusus. Untuk simpul, kami menggunakan kernel yang dioptimalkan untuk transformasi matriks dengan peningkatan akurasi FP24 / FP32 ( highp ). Untuk piksel, inti yang bekerja lebih efisien dengan akurasi FP16 ( mediump ) berkurang . Dengan highp inimereka tidak didukung. Sekilas, spesialisasi ini memungkinkan kami untuk mencapai distribusi transistor yang lebih rasional pada chip. Namun, dalam praktiknya, ini mengarah pada kesulitan dalam mengembangkan efek kompleks, serta ketika menggunakan tekstur resolusi tinggi. Selain itu, spesialisasi inti dapat menyebabkan bottleneck vertex / fragmen . Istilah ini mengacu pada situasi ketika, karena beban asimetris pada inti dan piksel inti, beberapa inti tersebut β€œidle”. 


Oleh karena itu, arsitektur modern menggunakan inti terpadu. Kernel seperti itu dapat mengambil tugas vertex, pixel dan komputasi lainnya tergantung pada beban.


Kumpulan instruksi vektor (SIMD) atau skalar


Dalam semangat keinginan untuk menghemat transistor yang dijelaskan di atas, yang berspesialisasi dalam inti, desain seperangkat instruksi shader terjadi. Transformasi paling umum untuk grafik tiga dimensi beroperasi dengan 4 vektor komponen. Oleh karena itu, GPU awal bekerja secara khusus dengan operan tersebut. Jika kode shader berisi operasi skalar heterogen yang tidak dapat dikemas ke dalam operasi vektor oleh pengoptimal, beberapa daya komputasi tidak digunakan. Fenomena ini dapat digambarkan sebagai berikut:


Ada shader yang mengimplementasikan operasi Tambahkan Multiply yang umum: multiply 2 operan, dan kemudian tambahkan yang ketiga. Ketika mengkompilasi pada arsitektur vektor bersyarat (Vector ISA = Vector Instruction Set Architecture) kita mendapatkan satu instruksi vektor vMADD , yang berjalan selama 1 jam. Pada arsitektur skalar bersyarat, kita mendapatkan 4 instruksi skalar, yang, berkat pipeline yang ditingkatkan, juga dieksekusi dalam siklus 1 jam. Sekarang pertimbangkan shader canggih yang melakukan 2 operasi, tetapi pada 2 komponen operan.


Dalam hal arsitektur vektor, kita sudah mendapatkan 2 instruksi yang memerlukan 2 siklus clock untuk dieksekusi. Namun, tidak ada tindakan yang diambil pada komponen .zw , dan daya pemrosesan idle. Dalam kasus arsitektur skalar, operasi yang sama ini dapat dikemas dalam 4 skadar sMADD yang berjalan dalam siklus 1 jam yang sama. Jadi, pada arsitektur skalar karena peningkatan pipa, kepadatan perhitungan yang lebih tinggi tercapai. Namun, seperti yang akan ditunjukkan di bawah ini, vektor ISA masih relevan. Jadi, masuk akal untuk menerapkan teknik vektorisasi untuk kode shader. Mereka memungkinkan Anda untuk mencapai peningkatan kinerja pada kartu video dengan vektor ISA . Pada saat yang sama, sebagai suatu peraturan, ini tidak merusak kinerja pada skalar yang lebih modernISA .

Berdasarkan karakteristik di atas, kami akan mempertimbangkan keluarga GPU seluler yang umum di zaman kita. Mari kita mulai dengan keluarga yang paling umum. Banyak orang tahu bahwa kita berbicara tentang kartu grafis Mali dari perusahaan Inggris ARM . ARM tidak terlibat langsung dalam produksi chip, melainkan menawarkan kekayaan intelektual. Seperti kartu video seluler lainnya, Mali adalah bagian dari System on Chip (SoC) , mis. bekerja dengan memori bersama untuk CPU dan GPU dan bus. 

Mali utgard


Pada 2008, perwakilan pertama arsitektur Mali Utgard lahir , relevan hingga hari ini. Kartu video ini dinamai sesuai dengan skema Mali-4 xx MP n , di mana xx adalah nomor model dan n adalah jumlah inti fragmen. Di Mali Utgard core shader khusus, dan semua model hanya hadir dengan 1 inti.

Fitur lain dari arsitektur Mali Utgard:

  • OpenGL ES 2.0 
  • Kurangnya dukungan highp di kernel terfragmentasi
  • Kumpulan instruksi vektor (masuk akal untuk membuat vektor perhitungan)

Terlepas dari spesifikasi OpenGL ES , driver kartu video Mali Utgard berhasil mengkompilasi shader fragmen yang menggunakan presisi highp (misalnya, akurasi diatur secara default menggunakan presisi highp float ). Tetapi akurasi mediump sebenarnya digunakan . Oleh karena itu, disarankan untuk menguji tambahan semua shader untuk game seluler pada kartu video tersebut. Menurut data yang dikumpulkan oleh Unity , pada akhir 2019, Mali Utgard mengerjakan perangkat untuk sekitar 10% pemain. Dan jika Anda mengatur filter yang sesuai pada market.yandex.ru , Anda dapat melihat bahwa pada tahun 2019 lebih dari 10 ponsel baru dengan kartu video dari arsitektur ini diumumkan.


Jika Anda siap untuk mengabaikan audiens ini, cukup dengan menetapkan persyaratan untuk dukungan OpenGL ES 3.0 di AndroidManifest.xml:

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

Selain Mali Utgard , saat ini tidak ada GPU seluler yang tersebar luas tanpa dukungan untuk OpenGL ES 3.0.

Catatan khusus adalah penggunaan tekstur resolusi tinggi di Mali Utgard . Sepuluh bit mantissa dengan akurasi sedang tidak cukup untuk tekstur berkualitas tinggi dengan resolusi tekstur lebih dari 1024 di satu sisi. Namun, meskipun hanya mendukung presisi media di inti fragmen Mali Utgard , Anda bisa mendapatkan akurasi koordinat tekstur fp24 saat menggunakan beragam secara langsung.

// 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 
                                                 //  
}

Sebagai bonus pada beberapa arsitektur, pendekatan ini memungkinkan Anda untuk prefetch konten tekstur sebelum menjalankan shader fragmen , yang meminimalkan warung sambil menunggu tekstur sampel hasil.

Midgard Mali


The Mali Utgard telah digantikan oleh Mali Midgard arsitektur . Ada beberapa generasi arsitektur ini dengan nama-nama spesies Mali-6xx , Mali-7xx dan Mali-8xx . Meskipun berusia 8 tahun, Mali Midgard dapat disebut arsitektur modern yang menyediakan dukungan untuk sebagian besar fitur baru:

  • kernel shader terpadu
  • OpenGL ES 3.2 (menghitung & geometri shaders, tesselation ...)

Namun, Mali Midgard mempertahankan ISA vektor . Mengingat meluasnya penggunaan Mali Midgard (sekitar 25% dari audiens kami), vektorisasi komputasi menjadi tepat.

Fitur lain dari Mali Midgard adalah teknologi Forward Pixel Kill . Setiap piksel dihitung dalam aliran terpisah dari inti fragmen. Jika selama pelaksanaan aliran diketahui bahwa piksel yang dihasilkan akan diblokir oleh piksel buram primitif lain, aliran berakhir sebelum waktunya dan sumber daya yang dibebaskan digunakan untuk perhitungan lainnya.

Mali bifrost


Di sebelah Midgard, arsitektur Bifrost menonjol karena transisinya ke skalar ISA . Dibandingkan dengan arsitektur sebelumnya, jumlah maksimum core telah ditingkatkan (dari 16 menjadi 32), dan antarmuka yang ditingkatkan dengan CPU didukung, yang memungkinkan akses yang koheren ke memori bersama: perubahan pada isi memori CPU / GPU segera menjadi "terlihat" satu sama lain meskipun ada cache, yang memungkinkan Anda menyederhanakan sinkronisasi.

Dari tidak resmi


Banyak upaya telah dilakukan untuk merekayasa balik kartu video Mali untuk membuat driver Open Source untuk Linux . Karya-karya orang-orang berdedikasi yang mencoba melakukan ini memungkinkan kita untuk melihat fitur-fitur kartu video Mali yang tidak berdokumen . Jadi, dalam proyek PanFrost ada disassembler untuk Mali Midgard / Bifrost , yang dengannya Anda bisa berkenalan dengan seperangkat instruksi shader (tidak ada informasi resmi terbuka tentang topik ini).


Adreno


Keluarga GPU ponsel kedua yang paling umum adalah Adreno . Kartu video ini dipasang di SoC , yang dikenal dengan merek Snapdragon , dari perusahaan Amerika Qualcomm . Snapdragon dipasang di smartphone kelas atas saat ini dari Samsung , Sony , dan lainnya.

Kartu video Adreno saat ini adalah keluarga seri 3xx - 6xx. Semua seri ini menggabungkan fitur-fitur berikut:

  • kernel shader terpadu
  • Pseudo TBR (ukuran ubin besar yang terletak di memori GPU khusus khusus)
  • Perpindahan otomatis dalam Mode Segera yang Rendering tergantung pada sifat adegan ( FlexRender )
  • Set instruksi skalar

Dimulai dengan Adreno 4xx , dukungan untuk OpenGL ES 3.1 diperkenalkan , dan dengan Adreno 5xx - Vulkan dan OpenGL ES 3.2 .

Render berbasis ubin Adreno


Kartu video Adreno memiliki GPU "tradisional" yang disebut GMEM . Volume dari 128kb hingga 1536kb berlaku. Ini memungkinkan Anda untuk menggunakan ukuran ubin yang lebih besar dibandingkan dengan arsitektur pengembang seluler GPU lainnya. Pada Adreno, ukuran ubin dinamis dan tergantung pada format warna yang digunakan, buffer kedalaman dan stensil. Saat bekerja dalam Mode Segera, rendering terjadi di memori sistem. Ada ekstensi GL ES yang memungkinkan Anda menentukan mode yang disukai: QCOM_binning_control . Namun, rekomendasi terbaru dari Qualcomm menyarankan untuk bergantung sepenuhnya pada driver GPU, yang dengan sendirinya menentukan mode yang paling disukai untuk buffer perintah yang dihasilkan aplikasi. 

Saat bekerja dalam mode TBR Adreno membuat 2 melewati simpul:

  1. Binning lulus - distribusi primitif oleh bin ( tempat sampah , sinonim untuk ubin)
  2. Pass vertex penuh untuk rendering hanya primitif yang termasuk dalam Bin saat ini

Selama operan Binning, Adreno hanya menghitung posisi titik. Atribut lain tidak dihitung, dan kode yang tidak perlu dihapus oleh pengoptimal. Dalam dokumentasi resmi (9.2 Optimize vertex processing), terdapat rekomendasi untuk menyimpan informasi vertex yang diperlukan untuk menghitung posisi secara terpisah dari data lainnya. Ini membuat caching data vertex lebih efisien.

Freedreno


Tidak seperti ARM dan Imagination Technologies, Qualcomm enggan berbagi rincian struktur internal GPU-nya. Namun, berkat upaya rekayasa balik Rob Clark, banyak yang dapat dipelajari dari proyek Freedreno , driver open source Adreno untuk Linux.

Rob Clark oleh Freedreno

PowerVR oleh Imagination Technologies


Imagination Technologies adalah perusahaan luar biasa asal Inggris yang terkenal karena mengembangkan GPU untuk produk Apple. Perusahaan melakukan peran ini sampai munculnya iPhone 8 / X, yang menggunakan pengembangan internal Apple. Meskipun rekomendasi pada optimasi untuk chip ini yang tetap tidak berubah, serta klaim paten terhadap Apple dari Imagination menunjukkan bahwa Apple terus mengembangkan arsitektur PowerVR, pengembangan asli dari Imagination. Pada awal 2020, Apple kembali ke praktik lisensi dengan Imagination Technologies. Selain perangkat dengan iOS / iPadOS, kartu video PowerVR dipasang di sejumlah besar smartphone dan tablet Android.


Pertimbangkan keluarga kartu grafis PowerVR yang masih dapat ditemukan di antara pengguna.

PowerVR SGX


Kartu grafis PowerVR SGX pertama kali muncul kembali pada tahun 2009. Ada beberapa generasi arsitektur ini: Series5, Series5XT dan Series5XE. Apple menggunakan GPU ini hingga iPAD 4 / iPhone 5 / iPOD Touch 5. Fitur-fitur SGX berikut dapat dikutip:

  • kernel shader terpadu
  • OpenGL ES 2.0
  • set instruksi vektor
  • mendukung presisi rendah 10-bit dalam shader
  • kinerja rendah dari ketergantungan tekstur berbunyi

Mari kita membahas beberapa di antaranya dengan lebih detail. 

Akurasi rendah


PowerVR SGX adalah satu-satunya up-to-date GPU mobile dengan
lowp dukungan hardware . Model PowerVR yang lebih baru, serta semua GPU modern dari vendor lain, sebenarnya menggunakan akurasi menengah . Menggunakan
lowp pada PowerVR SXG memungkinkan Anda untuk mencapai kepadatan komputasi yang lebih tinggi (lebih banyak operasi per siklus). Pada saat yang sama, operasi swizzle (permutasi komponen vektor) untuk lowp , tidak seperti presisi lainnya, tidak gratis. Fitur ini, serta rentang nilai sempit yang disediakan oleh lowp ([-2,2]), membatasi ruang lingkupnya. Pada saat yang sama, pengaturan lowp yang burukmengakibatkan artefak pada keluarga SGX tidak akan terlihat pada semua kartu grafis lain di mana mediump presisi akan benar-benar digunakan . Untuk alasan ini, Anda harus mempertimbangkan untuk menolak menggunakan lowp dalam shader.

Tekstur tergantung berbunyi


Seperti yang Anda ketahui, operasi pengambilan sampel tekstur adalah yang paling lambat karena harus menunggu hasil pembacaan memori. Dalam kasus SoC seluler, kita berbicara tentang memori sistem bersama dengan CPU. Untuk mengurangi jumlah akses ke memori yang lambat, cache tekstur digunakan. Untuk menghindari downtime di awal rasterisasi menggunakan tekstur, masuk akal untuk men-cache area yang digunakan terlebih dahulu. Jika shader fragmen menggunakan koordinat tekstur dilewatkan dari shader vertex tanpa perubahan, maka bagian tekstur yang diperlukan untuk caching dapat ditentukan sebelum shader fragmen dieksekusi. Jika shader fragmen mengubah koordinat tekstur atau menghitungnya menggunakan data dari tekstur lain, maka ini tidak selalu mungkin. Akibatnya, eksekusi shader fragmen dapat melambat.Kartu grafis PowerVR SGX sangat menyakitkan dalam skenario ini. Selain itu, bahkan penggunaan permutasi dari komponen koordinat tekstur (swizzle) mengarah ketekstur tergantung dibaca . Berikut adalah contoh program shader tanpa membaca tekstur tergantung .

program vertex

attribute highp vec2 a_texc;
varying highp vec2 v_texc;

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


program fragmen

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

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

Dalam hal ini:

program fragmen

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


Kartu video PowerVR dikembangkan lebih lanjut dalam arsitektur Rogue . Ada beberapa generasi arsitektur ini: dari Series6 ke Series9. Semua PowerVR Rogue memiliki fitur-fitur ini:

  • kernel shader terpadu
  • arsitektur instruksi skalar
  • dukungan untuk OpenGL ES 3.0+ (hingga 3.2, serta Vulkan API untuk penguasa baru) 

PowerVR TBDR


Seperti semua GPU seluler umum, PowerVR menggunakan pipa petak. Tetapi tidak seperti para pesaingnya, Imagination melangkah lebih jauh dan menerapkan rasterisasi primitif yang ditangguhkan , yang memungkinkan melewatkan naungan piksel tak terlihat terlepas dari urutan rendernya. Pendekatan ini disebut Tile Based Deferred Rendering , dan proses menghilangkan piksel tak terlihat disebut Hidden Surface Removal (HSR).


Penghapusan Permukaan Tersembunyi

Disarankan untuk menggambar geometri buram menjadi transparan dan tidak menggunakan Z Prepass, yang dalam kasus kartu video PowerVR di sebagian besar skenario akan menyebabkan pekerjaan yang tidak perlu. Namun, beberapa piksel transparan berturut-turut yang tumpang tindih satu sama lain sepenuhnya diarsir untuk mendapatkan warna yang benar, dengan mempertimbangkan pencampuran akun. Pixel transparan terakhir dapat dibuang jika diikuti oleh piksel buram. 

Teknologi Imajinasi Keterbukaan


Pembuat PowerVR telah menyediakan akses terbuka lebih banyak dokumentasi daripada pengembang GPU lainnya. Arsitektur pipa grafis dijelaskan secara rinci, serta seperangkat instruksi untuk arsitektur Rogue . Ada alat PVRShaderEditor yang nyaman , yang memungkinkan Anda untuk langsung menerima informasi profil pada shader, serta daftar yang dibongkar untuk Rogue.


Meskipun kehadiran terbatas kartu video PowerVR di lingkungan perangkat berbasis Android, masuk akal untuk mempelajari arsitektur mereka untuk pemrograman grafis yang kompeten untuk iOS.

GPU mobile mode langsung


Kami memeriksa kartu video seluler keluarga yang paling umum. Semua keluarga ini menggunakan arsitektur render ubin. Namun, ada kartu video seluler yang menggunakan pendekatan mode langsung tradisional . Inilah beberapa di antaranya:

  • nVIdia (Tegra SoC)
  • Semua keluarga Intel kecuali Gen 11 terbaru
  • Vivante GCxxxx (+ Arcturus GC8000)

Fitur kartu video seluler yang beroperasi dalam mode langsung adalah operasi pembersihan FBO yang mahal. Ingatlah bahwa pada arsitektur ubin, pembersihan layar penuh mempercepat rendering, memungkinkan pengemudi untuk tidak menambahkan operasi Muat konten lama ke memori ubin. Pada GPU mode langsung seluler , pembersihan layar penuh adalah operasi yang memakan waktu yang memungkinkan, antara lain, GPU seperti itu untuk "menghitung". Jika menambahkan pembersihan tidak mempercepat, tetapi memperlambat rendering, maka kemungkinan besar kami bekerja dengan GPU mode langsung . Yah, tentu saja, jangan lupa untuk menyebutkan bahwa pada mode GPU langsung, mengubah target adalah prosedur "bebas bersyarat".

Distribusi berbagai keluarga GPU seluler di antara para pemain kami


Berikut adalah statistik GPU seluler yang dikumpulkan dari para pemain kami di akhir tahun 2019:


Di bawah ini kami membuka segmen "Lainnya"


Berdasarkan data ini, kami melihat distribusi GPU dalam hal fitur utama mereka.


Vektor ALU (unit logika aritmatika) menjadi usang dan diganti dengan yang skalar. Saat ini, sebagian besar GPU seluler dengan set instruksi vektor adalah Mali Midgard , yang dapat dianggap rata-rata dalam kinerjanya. Karena vektorisasi, sebagai suatu peraturan, tidak memperlambat eksekusi pada ALU skalar, perlu mempertimbangkan vektorisasi sebagai teknik aktual untuk mengoptimalkan shader untuk ponsel. 

Kernel shader khusus sudah tidak digunakan lagi dan diganti dengan yang sudah disatukan. Vertex Bottleneck pada kerangka skeletal tidak lagi menakutkan. Kernel khusus hanya digunakan pada keluarga Mali-4xx (Utgard) . Ingatlah bahwa GPU ini hanya mendukung OpenGL ES 2.0 . Audiens kami memiliki sekitar 3,5% dari mereka.

Akhirnya, sebagian besar GPU seluler menggunakan pendekatan ubin. Mode Segera telah menjadi terpinggirkan dan dengan cepat diperas bersama dengan kartu video yang menggunakannya. Pangsa GPU mode langsung di pemain kami adalah sekitar 0,7%.

Tautan yang bermanfaat:


Terimakasih atas perhatiannya! Pada artikel selanjutnya dari seri ini, kami akan mempertimbangkan teknik untuk mengoptimalkan shader untuk Seluler.

All Articles