Sangat populer untuk membuat konten prosedural di dalam GPU misalnya dalam demoscene (menggambar quad tunggal untuk mengisi layar dan membiarkan GPU menghitung piksel).
Ray marching populer:
Ini berarti GPU sedang mengeksekusi sejumlah iterasi loop yang tidak diketahui per piksel (walaupun Anda dapat memiliki batas atas seperti maxIterations
).
Bagaimana cara memiliki loop panjang variabel memengaruhi kinerja shader?
Bayangkan psuedocode ray-marching sederhana:
t = 0.f;
while(t < maxDist) {
p = rayStart + rayDir * t;
d = DistanceFunc(p);
t += d;
if(d < epsilon) {
... emit p
return;
}
}
Bagaimana berbagai keluarga GPU arus utama (Nvidia, ATI, PowerVR, Mali, Intel, dll) terpengaruh? Vertex shaders, tetapi terutama shader fragmen?
Bagaimana cara dioptimalkan?
opengl
glsl
opengl-es2
raytracing
Akan
sumber
sumber
Jawaban:
Ada pembicaraan yang baik di GDC 2012 tentang jarak-ray lapangan GPU (dan topik lainnya): http://directtovideo.wordpress.com/2012/03/15/get-my-slides-from-gdc2012/
Sejauh kinerja berjalan, kartu grafis (kelas DX11) terbaru mengeksekusi shader pada unit SIMD yang menjalankan 32 "NVIDIA" atau 64 "AMD" berbaris. Kelompok-kelompok ini dikenal sebagai warps atau wavefronts. Untuk pixel shaders, setiap utas sama dengan satu piksel, jadi saya berharap bahwa unit SIMD memproses sesuatu seperti 8x4 (NVIDIA) atau 8x8 (AMD) blok piksel secara bersamaan. Kontrol percabangan dan aliran dilakukan per-muka gelombang, sehingga semua utas di muka gelombang harus berulang sebanyak piksel individual terdalam di muka gelombang itu. Topeng jalur SIMD akan mematikan eksekusi untuk piksel yang telah selesai, tetapi mereka masih harus diam-diam mengikuti kontrol aliran muka gelombang keseluruhan. Ini berarti, tentu saja, bahwa sistem ini jauh lebih efisien ketika percabangannya koheren,
Dalam pengalaman saya, overhead cabang masih cukup tinggi bahkan jika semua utas di cabang muka gelombang dengan cara yang sama. Saya telah melihat peningkatan kinerja dalam beberapa kasus dengan membuka gulungan untuk mengamortisasi beberapa overhead cabang. Namun, itu tergantung pada seberapa banyak pekerjaan yang Anda lakukan di setiap perulangan, tentu saja. Jika loop body memiliki cukup "barang" di dalamnya, membuka gulungan tidak akan menang.
sumber
Saya sarankan membaca Running Code di Teraflop: Bagaimana GPU Shader Cores Work (pdf) dari SIGGRAPH 2008: Beyond Programmable Shading . Ini berbicara tentang percabangan dinamis.
sumber
Berkenaan dengan percabangan dinamis, satu catatan tambahan (mungkin jelas, tetapi masih perlu diperhatikan untuk beberapa orang): itu dapat sangat mempengaruhi kinerja loop yang tidak gulungan (Anda jelas tidak dapat membuka gulungan loop jika ada jumlah iterasi yang tidak konstan) .
sumber
int s = 0;
sekarang untuk (int k = 1; k <= n; k ++) {s + = k;} sama seperti s = n * (n + 1) / 2
jadi itu tidak benar secara umum: D
sumber