OpenCL'de özyineleme neden yasaktır?


19

Işınlanmış görüntülerin oluşturulmasını hızlandırmak için OpenCL kullanmak istiyorum, ancak Wikipedia sayfasının Open CL'de özyinelemenin yasak olduğunu iddia ettiğini fark ettim . Bu doğru mu? Raytracing yaparken özyinelemeyi kapsamlı bir şekilde kullandığım için, hızlanmadan yararlanmak için bu önemli miktarda yeniden tasarım gerektirecektir. Özyinelemeyi engelleyen temel kısıtlama nedir? Etrafında bir yol var mı?


2
GPU'lar farklı bir şekilde çalışır. (Bazı mimariler) küresel bir "program yığını" kavramına sahip değildir, bu nedenle bu işlevlerde özyinelemeli işlev çağrıları yapılamaz. OpenCL muhtemelen en düşük ortak paydayı benimser, böylece GPU'larda taşınabilir kalması için tamamen izin vermez. Daha yeni CUDA donanımının bir noktada özyineleme desteği sağladığı görülüyor: stackoverflow.com/q/3644809/1198654
glampert

Yanıtlar:


27

Bunun nedeni, tüm GPU'ların işlev çağrılarını destekleyememesidir ve mümkün olsalar bile, işlev çağrıları oldukça yavaş olabilir veya çok küçük yığın derinliği gibi sınırlamaları olabilir.

Gölgelendirici kodu ve GPU hesaplama kodu her yerde işlev çağrılarına sahip gibi görünebilir, ancak normal koşullar altında derleyici tarafından% 100 satır içine alınır. GPU tarafından yürütülen makine kodu dallar ve döngüler içeriyor, ancak işlev çağrısı yok. Ancak, özyinelemeli işlev çağrıları açık nedenlerle satır içine alınamaz. (Bazı argümanlar derleme zamanı sabitleri olmadığı sürece, derleyici bunları katlayabilir ve tüm çağrı ağacını satır içine alabilir.)

Gerçek işlev çağrılarını uygulamak için bir yığına ihtiyacınız vardır. Çoğu zaman, gölgelendirici kodu hiç yığın kullanmaz - GPU'ların büyük kayıt dosyaları vardır ve gölgelendiriciler tüm verilerini sürekli olarak kayıtlarda tutabilir. Bir yığının çalışması zordur, çünkü (a) aynı anda uçuşta olabilecek tüm çözgüleri sağlamak için çok fazla yığın alanına ihtiyacınız olacak ve (b) GPU bellek sistemi çok fazla toplu iş için optimize edilmiştir yüksek işlem hacmi elde etmek için bellek işlemlerinin, ancak bu gecikme pahasına gelir, bu yüzden benim tahminim, yerel değişkenleri kaydetmek / geri yüklemek gibi yığın işlemleri çok yavaş olacaktır.

Tarihsel olarak, donanım düzeyindeki işlev çağrıları GPU'da çok yararlı olmamıştır, çünkü derleyicideki her şeyi satır içine almak daha mantıklıdır. Bu yüzden GPU mimarları onları hızlı yapmaya odaklanmadı. Muhtemelen bazı farklı dengesizlikler yapılabilir, eğer gelecekte donanım düzeyinde verimli aramalar için bir talep varsa, ancak (mühendislikteki her şeyde olduğu gibi) başka bir yerde maliyete neden olacaktır.

Işın izleme söz konusu olduğunda, insanların genellikle bu tür şeylerle başa çıkma şekli, izlenmekte olan ışınların kuyruklarını oluşturmaktır. Özyineleme yerine, bir kuyruğa bir ışın eklersiniz ve yüksek bir yerde, tüm kuyruklar boşalana kadar işlemeye devam eden bir döngünüz vardır. Bununla birlikte, klasik bir özyinelemeli raytracer'dan başlıyorsanız, oluşturma kodunuzun önemli ölçüde yeniden düzenlenmesini gerektirir. Daha fazla bilgi için, bu konuda okunacak iyi bir makale Wavefront Path Tracing'dir .


6
Bu gizli sosu paylaşmak istemiyorum, ancak sabit bir maksimum sıçrama sayısı olan ve bunu idare etmek için sabit bir boyutta (ve sabit sayıda iterasyona sahip bir döngü) sahip oldukça iyi şanslar yaşadım. Ayrıca (ve bu gerçek gizli sos imo!) Malzemelerim yansıtıcı veya kırıcı ama asla her ikisi de, bu yüzden ışınları sıçrama zaman bölünmez yapar yapar. Tüm bunların sonucu, özyinelemeli tip ışınlı oluşturmadır, ancak sabit boyutlu yineleme ile özyineleme değildir.
Alan Wolfe

Kuyruk özyineleme gibi mi?
Tanmay Patil

Kuyruk özyineleme işlevleri yinelemeli işlevlere dönüştürülebileceğinden kuyruk özyineleme gerçekleştirmek için bir yığına ihtiyacınız olmaz. OpenCL derleyicisi bunu otomatik olarak yapmıyor mu?
Anderson Green
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.