Putaran kinerja dalam shader

11

Saya bertanya-tanya apa cara terbaik untuk mengintegrasikan fungsi loop dinamis dalam shader?

Pertama, sepertinya array dinamis tidak mungkin. Jadi, apakah lebih baik membuat array ukuran maksimum dan hanya mengisi sebagian saja atau mendefinisikan array dengan ukuran yang sudah ditentukan sebelumnya?

Lalu, apa cara terbaik untuk beralih dari array ini?

Apakah lebih baik menggunakan loop yang tidak terbuka atau loop dinamis untuk sesuatu antara 4 hingga 128 iterasi? Saya juga telah melihat bahwa dimungkinkan untuk membuka gulungannya ke jumlah iterasi maksimum yang telah ditentukan kemudian menghentikannya dengan kondisi seperti if (i == myCurrentMaximumIterationNumber).

Tikar
sumber
2
Apa yang Anda coba lakukan dengan array dan loop? Saya bertanya karena ini entah bagaimana terdengar seperti Masalah XY bagi saya. Karena cara terbaik untuk menggunakan kondisi dan loop pada GPU adalah untuk tidak menggunakannya, mungkin ada cara yang lebih baik daripada menggunakan array dan loop dalam kasing Anda.
Nero
Saya menerapkan efek hamburan permukaan bawah layar yang saat ini berfungsi. Tetapi saya memiliki beberapa keraguan tentang cara saya menggunakan kernel menurut pertunjukan. Saya telah memilih untuk melakukan ukuran array maksimum dan hanya mengisi sebagian dan menggunakan loop dinamis dengan jumlah iterasi dinamis yang terkait dengan konten array yang saat ini digunakan. Saya berpikir bahwa ada hal-hal yang harus dilakukan atau diketahui ketika memprogram shader sesuai dengan pertunjukan misalnya. Dan menurut saya loop adalah topik kinerja umum yang mungkin mengikuti beberapa aturan dan mungkin "praktik yang baik" tetapi saya tidak menemukan jawaban yang baik tentang hal itu.
MaT

Jawaban:

6

Kompiler Shader sangat agresif membuka gulungan karena HW awal sering tidak memiliki kontrol aliran dan biaya pada HW yang lebih baru dapat bervariasi. Jika Anda memiliki tolok ukur yang secara aktif Anda uji dan berbagai perangkat keras yang relevan, cobalah hal-hal untuk melihat apa yang terjadi. Perulangan dinamis Anda lebih bisa menerima intervensi pengembang daripada perulangan statis - tetapi menyerahkannya ke kompiler masih merupakan saran yang bagus kecuali Anda memiliki tolok ukur yang tersedia. Dengan tolok ukur, eksplorasi bermanfaat (dan menyenangkan).

BTW, kerugian terbesar dengan loop dinamis pada GPU adalah bahwa "utas" individu di wavefront / warp akan selesai pada waktu yang berbeda. Utas yang berhenti nanti memaksa semua yang selesai lebih awal untuk menjalankan NOP.

Nested loop harus dipikirkan dengan saksama: Saya menerapkan dekoder entropi berbasis blok yang mengkodekan proses nol (untuk kompresi seperti JPEG). Implementasi alami adalah untuk memecahkan kode run dalam loop batin yang ketat - yang berarti sering hanya satu thread yang membuat kemajuan; dengan meratakan loop dan secara eksplisit menguji di setiap utas apakah saat ini sedang mendekode run atau tidak, saya menjaga semua utas aktif melalui loop panjang tetap (blok yang didekodekan semuanya berukuran sama). Jika utasnya seperti utas CPU, perubahannya akan mengerikan, tetapi pada GPU yang saya jalankan, saya mendapat peningkatan kinerja 6 kali lipat (yang masih mengerikan - tidak ada cukup blok untuk membuat GPU sibuk - tapi itu bukti konsep).

Daniel M Gessel
sumber