Domanda

Attualmente sto implementando un raytracer.Dato che il raytracing è estremamente pesante in termini di calcoli e poiché esaminerò comunque la programmazione CUDA, mi chiedevo se qualcuno ha qualche esperienza con la combinazione dei due.Non posso davvero dire se i modelli computazionali corrispondono e vorrei sapere cosa aspettarmi.Ho l'impressione che non sia proprio una partita perfetta, ma un discreto aumento di velocità sarebbe meglio di niente.

È stato utile?

Soluzione

Una cosa di cui prestare molta attenzione in CUDA è che il flusso di controllo divergente nel codice del kernel UCCIDE assolutamente le prestazioni, a causa della struttura dell'hardware della GPU sottostante.Le GPU in genere hanno carichi di lavoro estremamente paralleli con un flusso di controllo altamente coerente (ad es.hai un paio di milioni di pixel, ognuno dei quali (o almeno ampie porzioni dei quali) verrà gestito dal esatto stesso programma shader, anche prendendo la stessa direzione attraverso tutti i rami.Ciò consente loro di apportare alcune ottimizzazioni hardware, come avere solo una singola cache di istruzioni, unità di recupero e logica di decodifica per ciascun gruppo di 32 thread.Nel caso ideale, comune nella grafica, possono trasmettere la stessa istruzione a tutti i 32 set di unità di esecuzione nello stesso ciclo (questo è noto come SIMD o Single-Instruction Multiple-Data).Loro possono emulare MIMD (Multiple-Instruction) e SPMD (Single-Program), ma quando i thread all'interno di uno Streaming Multiprocessor (SM) divergono (prendono percorsi di codice diversi da un ramo), la logica del problema cambia effettivamente tra ciascun percorso di codice in un ciclo -base del ciclo.Puoi immaginare che, nel peggiore dei casi, quando tutti i thread si trovano su percorsi separati, l'utilizzo dell'hardware è diminuito di un fattore 32, eliminando di fatto qualsiasi vantaggio che avresti avuto eseguendo su una GPU su una CPU, in particolare considerando il sovraccarico associato al marshalling del set di dati dalla CPU, su PCIe, alla GPU.

Detto questo, il ray tracing, sebbene in un certo senso sia parallelo ai dati, ha un flusso di controllo ampiamente divergente anche per scene moderatamente complesse.Anche se riesci a mappare un gruppo di raggi ravvicinati che proietti uno accanto all'altro sullo stesso SM, la posizione dei dati e delle istruzioni che hai per il rimbalzo iniziale non durerà a lungo.Ad esempio, immagina che tutti i 32 raggi altamente coerenti rimbalzino su una sfera.Andranno tutti in direzioni abbastanza diverse dopo questo rimbalzo e probabilmente colpiranno oggetti realizzati con materiali diversi, con condizioni di illuminazione diverse e così via.Ogni materiale e set di illuminazione, occlusione, ecc.alle condizioni è associato un proprio flusso di istruzioni (per calcolare rifrazione, riflessione, assorbimento, ecc.), e quindi diventa abbastanza difficile eseguire lo stesso flusso di istruzioni anche su una frazione significativa dei thread in un SM.Questo problema, con l'attuale stato dell'arte del codice ray-tracing, riduce l'utilizzo della GPU di un fattore 16-32, il che potrebbe rendere le prestazioni inaccettabili per la tua applicazione, soprattutto se è in tempo reale (ad es.un gioco).Potrebbe comunque essere superiore a una CPU per es.una fattoria di rendering.

Esiste una classe emergente di acceleratori MIMD o SPMD attualmente esaminata nella comunità di ricerca.Li considererei piattaforme logiche per software, raytracing in tempo reale.

Se sei interessato agli algoritmi coinvolti e alla loro mappatura nel codice, dai un'occhiata a POVRay.Guarda anche la mappatura dei fotoni, è una tecnica interessante che si avvicina addirittura di un passo alla rappresentazione della realtà fisica rispetto al raytracing.

Altri suggerimenti

Si può certamente fare, è stato fatto, ed è un argomento caldo attualmente tra i guru del raytracing e di Cuda.Inizierei esaminando attentamente http://www.nvidia.com/object/cuda_home.html

Ma è fondamentalmente un problema di ricerca.Le persone che lo fanno bene ne ottengono documenti di ricerca sottoposti a revisione paritaria.Ma BENE a questo punto significa ancora che i migliori risultati GPU/Cuda sono approssimativamente competitivi con le soluzioni migliori della categoria su CPU/multi-core/SSE.Quindi penso che sia un po' presto per supporre che l'uso di Cuda accelererà un ray tracer.Il problema è che sebbene il ray tracing sia "imbarazzantemente parallelo" (come si suol dire), non è il tipo di problema di "dimensioni di input e output fisse" che si associa direttamente alle GPU: vuoi alberi, stack, strutture di dati dinamici, ecc. .Può essere fatto con Cuda/GPU, ma è complicato.

La tua domanda non era chiara riguardo al tuo livello di esperienza o agli obiettivi del tuo progetto.Se questo è il tuo primo ray tracer e stai solo cercando di imparare, eviterei Cuda: ti ci vorrà 10 volte di più per svilupparlo e probabilmente non otterrai una buona velocità.Se sei un programmatore Cuda con moderata esperienza e stai cercando un progetto stimolante e il ray tracing è semplicemente una cosa divertente da imparare, prova a farlo in Cuda.Se stai creando un'app commerciale e stai cercando di ottenere un vantaggio competitivo in termini di velocità, beh, probabilmente è una cazzata a questo punto...potresti ottenere un vantaggio in termini di prestazioni, ma a scapito di uno sviluppo più difficile e di una dipendenza da un particolare hardware.

Ricontrolla tra un anno, la risposta potrebbe essere diversa dopo un'altra generazione o due di velocità della GPU, sviluppo del compilatore Cuda ed esperienza nella comunità di ricerca.

Nvidia ha presentato una demo di un ray-tracer in CUDA alla conferenza NVision di quest'anno.Ecco un collegamento alle loro diapositive a riguardo.

http://www.nvidia.com/object/nvision08-IRT.html

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top