Implementazione di algoritmi tramite shader di calcolo e shader di pipeline


10

Con la disponibilità di shader di calcolo sia per DirectX che per OpenGL è ora possibile implementare molti algoritmi senza passare attraverso la pipeline di rasterizzazione e utilizzare invece il calcolo per scopi generali sulla GPU per risolvere il problema.

Per alcuni algoritmi questa sembra diventare la soluzione canonica intuitiva perché intrinsecamente non basata sulla rasterizzazione e gli shader basati sulla rasterizzazione sembravano essere una soluzione alternativa per sfruttare la potenza della GPU (semplice esempio: creare una trama del rumore. Nessun quad deve essere rasterizzato qui ).

Dato un algoritmo che può essere implementato in entrambi i modi, ci sono vantaggi generali (potenziali) in termini di prestazioni rispetto all'uso di shader di calcolo rispetto al percorso normale? Ci sono degli svantaggi a cui dovremmo prestare attenzione (ad esempio, c'è qualche tipo di sovraccarico insolito per passare da / per calcolare shader in fase di esecuzione)?

Ci sono forse altri vantaggi o svantaggi da considerare nella scelta tra i due?


Se il tag delle prestazioni è davvero pertinente, allora considera di guardare questo video dall'articolo "Cloth Simulation" di Game Engine Gems di Marco Fratarcangeli: youtube.com/watch?v=anNClcux4JQ . Puoi leggere i commenti e scoprire una cosa imbarazzante: l'implementazione basata su GLSL / shader è stata più veloce rispetto all'utilizzo di CUDA o OpenCL (quest'ultimo a causa del supporto scarso del driver al momento, nel 2010). Ci sono alcune differenze di basso livello che ... fanno la differenza.
Teodron,

@teodron Non ho gemme GPU disponibili e non riesco a trovare il codice sorgente. L'autore ha effettivamente utilizzato il vertex GLSL + pixel shader o ha usato gli shader di calcolo GLSL?
TravisG,

Sì! Prima di CUDA, è così che la community ha implementato le funzionalità GPGPU. Ecco un link a OpenCloth per vedere come si può ottenere proprio questo usando GLSL OR Cuda puro: code.google.com/p/opencloth/source/browse/trunk/…
teodron,

Risposte:


7

Non esiste una risposta giusta se si trarrà beneficio diretto dalla valutazione di shadrs / GPGPU di calcolo, questo dipende fortemente dal tipo di algoritmo che si sta implementando, i shader di calcolo e CUDA / OpenCL sono un approccio più generalizzato per superare alcune delle limitazioni di quei vecchi linguaggi di ombreggiatura hack. i vantaggi più importanti che otterrai:

  • Accesso alle informazioni spaziali. nel vecchio hack GLSL (beh, era un hack!) fornisce solo poche informazioni sui frammenti del vicino poiché utilizza le coordinate della trama. Negli shader di calcolo / CUDA / OpenCL l'accesso alle informazioni spaziali è molto più flessibile, ora puoi implementare algoritmi come l' equalizzazione dell'istogramma sulla GPU con accesso texture / buffer non ordinato.
  • Ti dà la sincronizzazione thread e atomica .
  • Calcola spazio: il vecchio hack GLSL collegherà lo spazio di calcolo vertice / frammento al tuo shader. Lo shader di frammenti verrà eseguito con il numero di frammenti, lo shader di vertici verrà eseguito con il numero di vertici. In compute shader definisci il tuo spazio.
  • Scalabilità : il tuo shader di calcolo / CUDA / OpenCL può scalare fino al numero di SM GPU (Streaming Multiprocessor) disponibili a differenza del tuo vecchio shader GLSL che dovrebbe essere eseguito sullo stesso SM. (Sulla base dei commenti di Nathan Reed, afferma che non è vero, e gli shader dovrebbero aumentare di livello quanto gli shader di calcolo dovrebbero. Non sono ancora sicuro di dover controllare la documentazione).
  • Cambio di contesto : dovrebbe esserci un cambio di contesto, ma direi che dipende dall'applicazione, quindi la soluzione migliore è profilare l'applicazione.

Bene, a mio avviso , se vuoi seguire il percorso degli shader di calcolo, anche se alcuni algoritmi possono essere più adatti, ci sono alcune considerazioni che devi prendere in considerazione:

  1. Hardware e compatibilità con le versioni precedenti . Gli shader di calcolo sono disponibili solo nell'hardware più recente e se stai cercando un prodotto commerciale (ad es. Un gioco) devi aspettarti che molti utenti potrebbero non essere in grado di eseguire il tuo prodotto.
  2. Di solito sono necessarie ulteriori conoscenze in architettura GPU / CPU , programmazione parallela e multithreading (ad es. Condivisione della memoria, coerenza della memoria, sincronizzazione dei thread, atomica e relativo effetto sulle prestazioni) che di solito non è necessario utilizzare normali shader rounte.
  3. Risorse di apprendimento , dall'esperienza ci sono molte meno risorse di apprendimento per Compute shadrs, OpenCL e CUDA (che offrono anche l'interoperabilità OpenGL) rispetto al solito percorso degli shader.
  4. Gli strumenti di debug , con la mancanza di un debug adeguato, lo sviluppo degli strumenti può diventare molto più difficile della maggior parte degli shader, almeno gli shader possono essere debug visivamente.
  5. Mi aspetto che gli shader di calcolo forniscano prestazioni migliori rispetto allo stesso algoritmo in altri shader; se sono stati fatti correttamente prendendo in considerazione le cose dal punto 2, poiché sono stati progettati per evitare i passaggi aggiuntivi per il rendering grafico. Ma non ho prove concrete a sostegno della mia richiesta.
  6. Dovresti anche prendere in considerazione CUUDA / OpenCL per GPGPU se stai seguendo quel percorso.

Tuttavia sono sicuro che sarà fantastico per il futuro e sarà una grande esperienza di apprendimento. In bocca al lupo!


Penso che l'OP potrebbe chiederlo: perché risolvere un problema usando shader GLSL puri anziché codificarlo in CUDA? C'è un articolo sulle gemme di programmazione del gioco relativo alla simulazione di tessuti in cui l'autore fa proprio questo. E il vecchio stile GLSL hacky è meglio del modo CUDA in termini di prestazioni. Probabilmente dovresti sottolineare perché se hai idea del perché.
Teodron,

2
Non penso che il tuo punto di scalabilità sia corretto: gli shader di vertici e frammenti sono altrettanto capaci di ridimensionare l'intera GPU come lo sono gli shader di calcolo. In realtà, gli shader di calcolo possono essere più difficili da ridimensionare, poiché le dimensioni del threadgroup e l'utilizzo della memoria condivisa possono porre ulteriori limiti su quanti thread shader possono essere eseguiti contemporaneamente.
Nathan Reed,

2
Inoltre, se stai popolando una trama (ad esempio generando rumore o facendo qualche altro algoritmo procedurale), nella mia esperienza uno shader di frammenti sarà più veloce di uno shader di calcolo se stai semplicemente valutando una formula per ogni pixel. La mia ipotesi è che l'ordine dei frammenti corrisponda all'ordine dei pixel interni piastrellati / sfrigolanti, ottenendo così una migliore posizione della memoria rispetto allo shader di calcolo che non è a conoscenza di questo ordine. Gli shader di calcolo sono più veloci solo se è possibile utilizzare le loro funzioni speciali, ad esempio la memoria condivisa, per accelerare molto le cose rispetto a uno shader di frammenti.
Nathan Reed,

2
OK, ultimo commento. :) Penso che la maggior parte delle GPU attuali abbiano una sorta di cambio di contesto o cambio di modalità quando si passa dalla grafica al calcolo e viceversa. Quindi, se si eseguono alcuni shader grafici, quindi si invia uno shader di calcolo, quindi si eseguono altri shader grafici, ecc., Si sta subendo un impatto sulle prestazioni quando si passa avanti e indietro. È qualcosa che dovresti profilare, ma potrebbe essere un altro motivo per restare fedeli agli shader grafici in un caso particolare.
Nathan Reed,

@NathanReed grazie per i commenti aggiornerò la mia risposta.
concept3d
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.