2012-05-25 7 views
9

Mi sono imbattuto in diverse situazioni in cui si afferma che fare un prodotto punto in GLSL finirà per essere eseguito in un ciclo. Ad esempio:GLSL - Un prodotto punto costa solo un ciclo?

Vertex e processori frammento operano su quattro vettori, eseguendo istruzioni quattro componenti quali addizioni, moltiplicazioni, moltiplicano-accumula, o prodotti dot in un singolo ciclo.

http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter35.html

Ho visto anche un credito nei commenti qualche parte che:

dot(value, vec4(.25)) 

sarebbe un modo più efficiente per media quattro valori, rispetto a:

(x + y + z + w)/4.0 

Ancora, il reclamo era che dot (vec4, vec4) sarebbe stato eseguito in un ciclo.

Vedo che ARB says that dot product (DP3 and DP4) and cross product (XPD sono istruzioni singole, ma significa che quelli sono altrettanto dispendiosi dal punto di vista computazionale rispetto a un vec4 add? Esiste fondamentalmente qualche implementazione hardware, sulla falsariga del moltiplicare-accumulare sugli steroidi, qui in gioco? Posso vedere come qualcosa di simile sia utile nella computer grafica, ma facendo in un ciclo ciò che potrebbe essere un po 'di istruzioni da solo sembra molto.

risposta

11

La domanda non può essere risolta in alcun modo definitivo nel suo insieme. Per quanto tempo qualsiasi operazione richiede hardware non è solo specifica dell'hardware, ma anche codice specifico. In altre parole, il codice circostante può mascherare completamente le prestazioni di un'operazione, oppure può richiedere più tempo.

In generale, non si deve presumere che un prodotto punto sia a ciclo singolo.

Tuttavia, ci sono alcuni aspetti che possono certamente essere risolta:

Ho visto anche un credito nei commenti qualche parte che:

sarebbe un modo più efficiente per media quattro valori, rispetto a:

mi sarebbe aspettatevi di essere un pò vero, purché x, y, z e w sono infatti diversi valori float piuttosto che membri dello stesso vec4 (ovvero, non sono value.x, value.y, ecc.). Se sono elementi dello stesso vettore, direi che qualsiasi compilatore di ottimizzazione decente dovrebbe compilare entrambi allo stesso insieme di istruzioni. Un buon peephole optimizer dovrebbe catturare modelli come questo.

Dico che è "un po 'vero", perché dipende dall'hardware. La versione del prodotto dot non dovrebbe per lo meno essere più lenta. E ancora, se sono elementi dello stesso vettore, l'ottimizzatore dovrebbe gestirlo.

singole istruzioni, ma vuol dire che sono altrettanto computazionalmente costosi come fare un vec4 add?

Non si deve presumere che il montaggio ARB ha qualsiasi relazione al codice di istruzione macchina hardware vero e proprio.

Esiste fondamentalmente qualche implementazione hardware, sulla falsariga di moltiplicare-accumulare sugli steroidi, in gioco qui?

Se si vuole parlare di hardware, è molto specifico dell'hardware. C'era una volta, c'era l'hardware specializzato per i prodotti puntini. Questo è stato ai tempi del cosiddetto "bumpmapping DOT3" e della prima era degli shader.

Tuttavia, al fine di accelerare le operazioni generali, hanno dovuto prendere questo genere di cose. Così ora, per la maggior parte dell'hardware moderno (ovvero: qualsiasi dispositivo Radeon classe HD o NVIDIA 8xxx o superiore, il cosiddetto DX10 o 11 hardware), i prodotti puntini fanno praticamente quello che dicono di fare. Ogni moltiplicazione/aggiunta riprende un ciclo.

Tuttavia, questo hardware consente anche molto parallelismo, quindi è possibile avere 4 prodotti vec4 separati contemporaneamente. Ognuno prenderebbe 4 cicli. Ma, fintanto che i risultati di queste operazioni non vengono utilizzati negli altri, possono essere eseguiti tutti in parallelo. E quindi, i quattro di loro totali richiederebbero 4 cicli.

Quindi, di nuovo, è molto complicato. E dipendente dall'hardware.

La soluzione migliore è iniziare con qualcosa che è ragionevole. Poi scopri l'hardware che stai cercando di codificare e lavora da lì.

+0

Ok, grazie. "Non dovresti assumere che l'assemblaggio ARB abbia alcuna relazione con il codice di istruzioni della macchina hardware". è fondamentalmente la risposta concisa che speravo. Sembra proprio che ARB sia un po 'di nicchia e difficile trovare un sacco di materiale su Google. Questo era uno di quei tipi di "conoscenza tribale" che non riuscivo a verificare, e il fatto che fosse vero per un periodo di tempo ha un senso. Roba forte. – ultramiraculous

0

la chiave è che un vec4 può essere "attivato" su un'unica istruzione (vedere il lavoro svolto da Intel su operazioni di registrazione a 16 byte, ovvero gran parte della base per il framework accelerato IOS).

se si inizia a dividere e dividere il vettore, non ci sarà più un "singolo indirizzo di memoria" del vettore per eseguire l'operazione.

4

Nicol Bolas ha gestito la risposta pratica, dal punto di vista di "assemblaggio ARB" o guardando le discariche IR. Mi occuperò della domanda "Come può 4 multipli e 3 aggiunge essere un ciclo nell'hardware ?! Sembra impossibile.".

Con pipelining pesante, qualsiasi istruzione può essere fatta per avere un ciclo di un throughput, non importa quanto complessa.

Non confondere questo con un ciclo di latenza!

Con esecuzione completamente pipeline, un'istruzione può essere distribuita in più fasi della pipeline. Tutte le fasi della pipeline funzionano contemporaneamente.

Ogni ciclo, il primo stadio accetta una nuova istruzione e le sue uscite passano allo stadio successivo. Ogni ciclo, un risultato esce dalla fine della pipeline.

Esaminiamo un prodotto a 4 punti, per un nucleo ipotetico, con una latenza di 3 cicli e una latenza di aggiunta di 5 cicli.

Se questa pipeline è stata progettata nel modo peggiore, senza alcun parallelismo vettoriale, sarebbero 4 moltiplicazioni e 3 aggiunte, per un totale di 12 + 15 cicli per una latenza totale di 27 cicli.

Ciò significa che un prodotto con punti richiede 27 cicli? Assolutamente no, perché può avviarne uno nuovo ad ogni ciclo, e ottiene la risposta 27 cicli dopo.

Se fosse necessario fare un prodotto con un punto e si dovesse attendere la risposta, si dovrà attendere la piena latenza a 27 cicli per il risultato. Se, tuttavia, dovessi calcolare 1000 punti per punti diversi, sarebbero necessari 1027 cicli. I primi 26 cicli, non ci sono stati risultati, nel 27 ° ciclo il primo risultato è uscito alla fine, dopo che è stato emesso il millesimo input, ci sono voluti altri 26 cicli per far uscire gli ultimi risultati alla fine. Questo rende il prodotto punto prendere "un ciclo".

I processori reali hanno il lavoro distribuito tra gli stadi in vari modi, dando più o meno stadi della pipeline, quindi potrebbero avere numeri completamente diversi da quelli che ho descritto sopra, ma l'idea rimane la stessa. Generalmente, meno lavoro fai per fase, più breve può diventare il ciclo di clock.

+0

Questa è una risposta descrittivamente formulata e la apprezzo pienamente come tale! –