Ini pada dasarnya karena tidak semua GPU dapat mendukung panggilan fungsi - dan bahkan jika mereka bisa, panggilan fungsi mungkin sangat lambat atau memiliki keterbatasan seperti kedalaman tumpukan yang sangat kecil.
Kode shader dan kode komputasi GPU mungkin tampak memiliki panggilan fungsi di semua tempat, tetapi dalam keadaan normal semuanya 100% digarisbawahi oleh kompiler. Kode mesin yang dijalankan oleh GPU berisi cabang dan loop, tetapi tidak ada panggilan fungsi. Namun, panggilan fungsi rekursif tidak dapat diuraikan karena alasan yang jelas. (Kecuali beberapa argumen adalah konstanta waktu kompilasi, sedemikian rupa sehingga kompiler dapat melipatnya dan menyejajarkan seluruh pohon panggilan.)
Untuk mengimplementasikan panggilan fungsi yang sebenarnya, Anda perlu tumpukan. Sebagian besar waktu, kode shader tidak menggunakan tumpukan sama sekali — GPU memiliki file register besar dan shader dapat menyimpan semua data mereka dalam register sepanjang waktu. Sulit untuk membuat stack bekerja karena (a) Anda akan membutuhkan banyak ruang stack untuk menyediakan semua warps yang dapat terbang dalam satu waktu, dan (b) sistem memori GPU dioptimalkan untuk batching bersama banyak. transaksi memori untuk mencapai throughput yang tinggi, tetapi ini datang dengan biaya latensi, jadi dugaan saya adalah operasi tumpukan seperti menyimpan / mengembalikan variabel lokal akan sangat lambat.
Secara historis, panggilan fungsi tingkat perangkat keras tidak terlalu berguna pada GPU, karena lebih masuk akal untuk memasukkan semua yang ada di kompiler. Jadi arsitek GPU belum fokus untuk membuatnya cepat. Mungkin beberapa tradeoff yang berbeda dapat dibuat, jika ada permintaan untuk panggilan tingkat perangkat keras yang efisien di masa depan, tetapi (seperti halnya semua hal dalam rekayasa) akan dikenakan biaya di tempat lain.
Sejauh menyangkut raytracing, cara orang biasanya menangani hal semacam ini adalah dengan membuat antrian sinar yang sedang dalam proses dilacak. Alih-alih berulang, Anda menambahkan ray ke antrian, dan pada tingkat tinggi di suatu tempat Anda memiliki loop yang terus memproses sampai semua antrian kosong. Itu memang membutuhkan reorganisasi yang signifikan dari kode rendering Anda jika Anda mulai dari raytracer rekursif klasik. Untuk info lebih lanjut, makalah yang bagus untuk dibaca tentang ini adalah Wavefront Path Tracing .