Esibizione ad anello in uno shader


11

Mi chiedo qual è il modo migliore per integrare una funzione di loop dinamico in uno shader?

Innanzitutto, sembra che le matrici dinamiche non siano possibili. Quindi, è meglio creare un array di dimensioni massime e riempirne solo una parte o definire array con dimensioni predefinite?

Quindi, qual è il modo migliore per scorrere su questo array?

È meglio usare un ciclo non srotolato o un ciclo dinamico per qualcosa tra 4 e 128 iterazioni? Ho anche visto che è possibile srotolarlo ad un numero massimo predefinito di iterazioni e poi fermarlo con una condizione come if (i == myCurrentMaximumIterationNumber).


2
Cosa stai cercando di fare con l'array e il loop? Sto chiedendo perché questo in qualche modo suona come un problema XY per me. Poiché il modo migliore per utilizzare condizioni e loop sulla GPU è astenersi dall'utilizzarli, forse ci sono modi ancora migliori invece di utilizzare array e loop nel tuo caso.
Nero

Sto implementando un effetto di scattering del sottosuolo dello schermo che attualmente funziona. Ma ho qualche dubbio sul modo in cui uso il kernel in base alle prestazioni. Ho scelto di eseguire una dimensione massima dell'array, riempire solo una parte e utilizzare un loop dinamico con un numero dinamico di iterazione correlato al contenuto dell'array attualmente utilizzato. Penso che ci siano cose da fare o da sapere quando si programmano shader in base alle prestazioni, ad esempio. E a mio avviso i loop sono un argomento di performance comune che potrebbe seguire alcune regole e forse "buone pratiche", ma non ho trovato alcuna buona risposta al riguardo.
MaT

Risposte:


6

I compilatori di shader sono estremamente aggressivi riguardo allo srotolamento poiché i primi HW spesso non avevano il controllo del flusso e il costo degli HW più recenti può variare. Se hai un benchmark a cui stai testando attivamente e una gamma di hardware pertinente, prova a vedere cosa succede. Il tuo loop dinamico è più suscettibile all'intervento degli sviluppatori rispetto a un loop statico, ma lasciarlo al compilatore è comunque un buon consiglio a meno che tu non abbia un benchmark disponibile. Con un benchmark, l'esplorazione è utile (e divertente).

A proposito, la più grande perdita con un loop dinamico su una GPU è che i singoli "thread" in un fronte d'onda / ordito finiranno in tempi diversi. I thread che si fermano in seguito costringono tutti quelli che finiscono presto ad eseguire i NOP.

I cicli nidificati dovrebbero essere attentamente valutati: ho implementato un decodificatore entropico basato su blocchi che codificava esecuzioni di zeri (per la compressione come JPEG). L'implementazione naturale era quella di decodificare le corse in un circuito interno stretto, il che significava che spesso stava facendo solo un thread; appiattendo il loop e testando esplicitamente in ogni thread se stava attualmente decodificando una corsa o meno, ho mantenuto tutti i thread attivi attraverso il loop a lunghezza fissa (i blocchi decodificati avevano tutte le stesse dimensioni). Se i thread fossero come i thread della CPU, il cambiamento sarebbe stato terribile, ma sulla GPU su cui stavo funzionando, avrei ottenuto un aumento di 6 volte delle prestazioni (che era ancora terribile - non c'erano abbastanza blocchi per mantenere occupata la GPU - ma era una prova di concetto).

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.