di  -  mercoledì 20 gennaio 2010

Questa settimana interromperemo temporaneamente la serie di articoli sui sensori digitali per affrontare un argomento piuttosto attuale. Sui forum di tutto il mondo si è parlato e si parla ancora di Fermi, Larrabee, delle nuove GPU DX11 di ATi/AMD; uno degli argomenti più dibattuti è quello relativo al tipo di implementazione di alcune funzionalità.

Da un lato ci sono i fautori dell’implementazione di tipo hardware, con unità dedicate a svolgere uno specifico task, dall’altro quelli i sostenitori dell’emulazione via software di determinate funzionalità, con i calcoli affidati ad unità di tipo generico.

Sollecitato, ancora una volta, dal mio amico pleg, ho deciso di inaugurare una serie di articoli su questo argomento, che serviranno da spunto anche per approfondimenti sulle architetture dei vari chip menzionati in precedenza. Il tutto, ovviamente, procederà di pari passo con la mini rubrica sui sensori digitali, alternandosi in una sorta di multitasking.

Stabilire  a priori se una strada sia migliore dell’altra è molto difficile. Nel corso degli anni, chi ha seguito l’evoluzione delle architetture delle GPU, ha assistito al passaggio da chip con alu dedicate ad uno specifico compito a chip con alu “generiche”, i cosiddetti shader unificati.

In quel caso specifico si è assistito ad un notevole boost prestazionale, dovuto alla maggior efficienza di un’architettura di questo ultimo tipo. La cosa, però non deve trarre in inganno e portare a concludere che l’utilizzo di unità dedicate sia sempre controproducente.

La prima distinzione va fatta proprio a livello di dimensioni del blocco funzionale che si va a sostituire. Se rimpiazzo sia il pixel che il vertex shader engine con un core a shader unificati, il vantaggio non deriva dalla velocità di esecuzione della singola operazione su una specifica unità che, anzi, in un’architettura unificata risulta più lenta, quanto dal fatto che riesco a sfruttare meglio l’intera architettura del chip.

Fatta questa premessa, partiremo proprio da considerazioni derivanti dal passaggio imposto dalle DX10 per poi andare a vedere, in alcuni casi specifici, come i vari progettisti hanno deciso di risolvere, di volta in volta, il, dilemma se rimpiazzare o tenere unità dedicate o di tipo fixed function.

Fino alla generazione DX9 la situazione era schematizzabile nel modo seguente:

g70

nell’immagine è riportato lo schema del G70 (7800, 7900, 7950) di nVIDIA. in cui si distinguono chiaramente i 3 principali blocchi di unità funzionali. Il primo che comprende le 8 unità di vertex shading e l’engine che si occupa di effettuare le operazioni di triangle setup, clipping, z-culling ecc.;il secondo blocco è quello che si occupa delle operazioni di pixel shading e texturing; infine c’è il terzo gruppo di unità, dette ROP’s ( o raster operation pipeline) che si incaricano delle operazioni di z-buffering, di “colorare” materialmente i pixel in base ai risultati delle operazioni matematiche, facendo color a alpha blending, di applicare il MSAA.

L’elaborazione di un’immagine 3D era quindi schematizzabile come un flusso di dati e istruzioni che viaggiano da un blocco funzionale all’altro nel modo seguente.

schema pipeline 3d

In un siffatto schema, ogni unità di calcolo ha un compito ben specifico da eseguire. Le cose non erano così lineari neppure ai tempi delle DX9, in realtà, perchè, ad esmepio, rispetto allo schema mostrato qui sopra, le operazioni di texture fetch, su texture non filtrate, erano possibili anche per le unità di vertex shading (le DX9c hanno introdotto il vertex texturing).

Occorre fare una considerazione: il carico tra le operazioni geometriche e le altre, ancora oggi è distribuito in maniera tale che le rpime pesino per circa il 30% e le altre per il restante 70% circa.

Questo per vari motivi non ultimo il fatto che, ad esempio, le operazioni di pixel shading sono quelle a latenze più elevate per mascherare le quali si ha bisogno di un gran numero di thread in circolo. Con lo schema precedente, ogni blocco funzionale riceve i dati da quello precedente e prima che ciò avvenga non può iniziare la sua elaborazione. Così, ad esmepio, i pixel shader possono operare solo dopo che il triangle setup engine ha “sfornato” le primitive su cui lavorare.

Allo stesso modo, una volta che i vertex shader, una volta inviati i dati elaborati passano alle successive istruzioni e vanno avanti fino a che non hanno riempito un buffer, presente tra la pipeline geometrica ed il pixel shader core, che contiene i dati destinati alla successiva elaborazione da parte dei pixel shader. Riempito questo buffer, restano in idle fino a che i pixel shader non hanno terminato il loro lavoro. Chiaro, quindi che è praticamente impossibile avere la piena occupazione di tutte le unità funzionali con una siffatta architettura. La situazione che ho tentato di descrivere a parole, è schematizzata da questa immagine

shader dedicati workload

Immagino che qualcuno di coi abbia visto più volte questa slide (una di quelle mostrate alla presentazione di G80). La figura mostra che nel caso in cui l’elaborazione geometrica sia molto pesante, si ha una situazione in cui i VS (vertex shader) risultano occupati al 100% mentre i pixel shader sono in “vacanza”. Al contrario, quando il carico di lavoro grava tutto o quasi sui PS (pixel shader) questi sono iper impegnati e i VS sono alle Maldive.

L’idea di poter utilizzare meglio il silicio, ha spinto i progettisti ad abbracciare la filosofia degli shader unificati

shader unificati

Come si vede dallo schema, in questo caso, le stesse unità si occupano delle operazioni di pixel e vertex shading, della gestione della fisica, dei geometry shader (introdotti con le DX10), ecc.

Questo dovrebbe far cambiare lo stato di occupazione delle unità nel modo seguente

shader unificati workload

Insomma, a giudicare da quest’ultima immagine, pare si sia trovato il classico uovo di Colombo (rigorosamente maiuscolo). La situazione, in effetti, è migliorata notevolmente: magari non nel modo illustrato anche perchè non tutte le architetture a shader unificati hanno lo stesso rendimento (ma questo è un altro discorso).

Dalle slide e dalle considerazioni precedenti, risulta chiaro che il vantaggio degli shader unificati risiede nell’ottimizzazione del lavoro dell’intero chip e non nella maggior efficienza della singola operazione.

Anzi, quest’ultima diminuisce in quanto mentre prima ogni unità aveva il suo compito specifico e “sapeva cosa fare” con alu di tipo generico ogni unità ha in coda istruzioni relative a diversi tipi di dati; quindi, di volta in volta, qualcuno deve dirle cosa fare e in che modo. Per questo motivo, in un chip a shader unificati aumenta notevolmente la complessità dei circuiti preposti a controllare ed organizzare il lavoro del chip;  questa complessità è tanto maggiore quanto più ci si sposta da architetture in cui gran parte del lavoro di scheduling è affidato al compilatore, ad architetture dove la totalità della distribuzione del workload è gestito in hardware.

Abbiamo visto come a livello macroscopico, l’abbandono di unità dedicate a svolgere un particolare task abbia portato notevoli benefici ma questo è stato essenzialmente dovuto alla possibilità di organizzare e gestire in maniera diversa il lavoro dell’intero chip. C’è anche da specificare che, dal punto di vista funzionale, l’aver sostituito due unità una dedicata ai VS ed una ai PS con una unica esegua entrambi i tipi di istruzioni (più altri) non ha comportato grandi problemi, in quanto le operazioni svolte sono sempre le medesime.

Diverso il discorso ed anche i risultati ottenuti, quando si è tentato di seguire altre strade. Ad esempio, si può ricordare il caso dell’R600 di ATi, in cui le operazioni di resolve del MSAA erano eseguite dallo shader core e non dalle ROP’s. In tal caso, il risultato è stato che le prestazioni, con MSAA attivo,  calavano vistosamente.

Dopo di allora, nessuno ha più tentato l’esperimento del resolve del MSAA via shader e, persino con le ultime versioni di API che prevedono anche l’adozione di filtri di tipo custom, persino di tipo non lineare e, quindi, non applicabili via ROP’s, il circuito che fa interpolazione lineare dei sample del MSAA box delle ROP’s è rimasto al suo posto.

Evidentemente, in questo caso, il vantaggio di avere unità di tipo generico e quindi riutilizzabili per altri compiti non era compensato dalla perdita di prestazioni di un’implementazione via software dell’operazione di resolve. Si, perché, di fatto, l’avere unità generiche ha come vantaggio quello di poter riutilizzare le stesse per più task; questo significa un notevole risparmio quando i blocchi da rimpiazzare sono di grandi dimensioni (l’intero shader core di un chip unificato rappresenta un bel vantaggio in termini di numero di unità generiche che si riescono a realizzare e, quindi, lo svantaggio di avere la singola unità meno veloce di una dedicata è compensato dall’elevato numero e dalla maggior efficienza del chip).

Lo svantaggio, di contro, è quello della minor velocità d’esecuzione della singola unità; quindi quando le unità da rimpiazzare sono poche o la loro sostituzione obbliga all’esecuzione di operazioni che richiedono molti più cicli di clock per essere portate a compimento, l’adozione di unità generich diventa controproducente.

Dopo quello del MSAA su R600, un altro esempio che mi viene in mente è quello del tessellator. In questo caso la sua funzione è possibile emularla utilizzando i vertex shader ma l’emulazione può avvenire a diversi livelli, perché si tratta di un blocco funzionale composto da più stadi, alcuni programmabili ed altri no. Ad esempio, abbiamo visto le implementazioni che ne ha fatto ATi. Prendiamo come riferimento gli utlimi due chip, RV770 ed RV870 e schematizziamo la pipeline grafica nel modo seguente

pipeline gpu

dove in grigio sono segnati gli stadi composti da fixed function; questa è una pipeline DX10; con le DX11 è stato aggiunto il tessellator, a monte delle unità di vertex shading. Anche il tessellator è composto da fixed function e stadi programmabili. In particolare, questi utlimi sono noti come hull shader e domain shader. ‘implementazione che ne ha fatto ATi in RV770, prevede che hull e domain shader siano emulati da vertex e geometry shader rispettivamente mentre rimane la parte del tessellator vera a propria, composta da fixed function. In RV870, invece, seguendo pedissequamente le specifiche DX11, hull e domain shader sono diventati due stadi fisicamente presenti sul chip e non più emulati, secondo lo schema seguente:

tesseellator

dove l’input assembler è un po’ più complesso di come è schematizzato nella figura.

Con Fermi, nVIDIA ha adottato una soluzione simile  a quella vista per RV770, con hull e domain shader rimpiazzati da vertex e geometry shader che ne emulano le funzionalità. Lo schema proposto in GF100 è il seguente

Fermi GPC

nell’immagine è riportato uno dei 4 GPC (graphic processing cluster) che compongono Fermi. E, in basso, è riportato, in dettaglio, lo schema del polymorph engine

fermi polymorph engine

Il polymorph engine racchiude tutti gli stadi di tipo fixed function che compongono la prima parte della pipeline grafica dedicata alle operazioni geometriche mentre il raster engine gli elementi di tipo fixed function che concorrono alle operazioni di rasterizzazione. L’approccio di nVIDIA differisce da quello visto su RV770 per il fatto che, in Fermi, sia la parte relativa alle operazioni di vertex fetch e di tessellation che quella relativa alle operazioni di rasterizzazione risulta distribuita. Ma di questo ci occuperemo quando tratteremo l’architettura di Fermi più in dettaglio. Di certo, la strada intrapresa da nVIDIA si pone a metà strada tra quella di ATi e quella, che vedremo tra poco, scelta da Intel, in quanto fa uso di fixed function per le operazioni che potrebbero portare via più cicli (la tessellation vera  e propria) e ricorre all’emulazione per le altre.

Un approccio ancora diverso è proprio quello proposto da Intel con Larrabee, in cui, a questo stadio, scompaiono le fixed function che vengono sostituite da unità programmabili. Anche di Larrabee mi occuperò più in dettaglio, in quanto l’idea di far uso, il più possibile, di unità programmabili su una gpu è piuttosto interessante. Cercheremo di scoprire insieme se e quanto sarà effettivamente applicabile ed efficace.

Altro vlocco funzionale che resta dotato di fixed function è quello denominato RBE (render back end). Se per le operazioni di pixel e vertex shading è più semplice un approccio con unità di tipo programmabili, per le RBE abbiamo visto come, nel caso del MSAA di R600, la cosa può creare non pochi problemi dovuti alla scarsa efficienza dell’emulaizone SW di alcune funzioni.

Ma se nei chip ATi e nVIDIA le RBE sono rimaste di tipo fixed function, il Larrabee sono diventate anch’esse programmabili. Non approfondirò, per ora, l’argomento ma faccio solo cenno al fatto che il maggrio problema a cui sono andati incontro i tecnici INtel è stato quello di poter rendere efficiente la loro alu di tipo vettoriale presente su ogni core di Larrabee.

Se, infatti, vettorializzare pixel e vertex shader è stata un’operazione abbastanza semplice (è bastato prendere come input quad di 4×4 pixel e batch di 16 vertici), lo stesso è risultato molto complesso nel caso di operazioni che sono, per loro natura, di tipo difficilmente parallelizzabile in quanto hanno una natura intrinsecamente scalare.

Dopo vari tentativi, e dopo svariati algoritmi provati e scartati perchè troppo lenti rispetto all’hardware dedicato, alla fine gli sforzi del team messo in gioco da Intel hanno dato i suoi frutti anche se, riporto le testuali parole di uno degli sviluppatori di questo algoritmo, Michael Abrash

software rasterization will never match dedicated hardware peak performance and power efficiency for a given area of silicon, but so far it’s proven to be efficient enough. It also has a significant advantage, which is that because it uses general purpose cores, the same resources that are used for rasterization can be used for other purposes at other times, and vice-versa

Quindi, per stessa ammissione dei tecnici e degli ingeneri di Intel, la loro soluzione software non è veloce come l’hardware dedicato ma ha il vantaggio di impiegare unità riutilizzbili pep altri task. C’è da vedere quanto il compromesso scelto da Intel inciderà negativamente sulle prestazioni e quanto porterà in termini di vantaggio di spazio guadagnato sul die per permettere l’allocazione di altre unità o per contenere i consumi.

Il campo sul quale anche INtel ha dovuto arrendersi è quello delle operazioni di texturing e, in particolare, quello delle operazioni di texture sampling. Nonostante gli sforzi profusi, il miglior risultato ottenuto con l’emulazione è stato quello di essere circa 20 volte più lenti che non con hardware dedicato. Quindi anche Larrabee avrà, al suo interno, delle fixed function. Un approccio analogo hanno seguito anche nVIDIA e ATi con i loro chip di ultima generazione, in cui le operazioni di texture sampling e texture addressing sono svolte da hardware dedicato mentre quelle di  blending dallo shader core.

Nelle prossime puntate di questa mini serie, approfondiremo alcuni aspetti delle architetture dei chip menzionati in questo articolo cercando, nei limiti del possibile, di scoprire quali saranno le prospettive future della grafica 3D e del GPU computing.

34 Commenti »

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.

  • # 1
    Alessio
     scrive: 

    Bene, anche se non sono un appassionato di grafica 3D mi è piaciuta la semplice ma completa spiegazione.

    Non aspetto altro che leggere l’articolo sul GPGPU e penso relative librerie proprietarie (Cuda, stream e directcompute) oltre alle open (CL) e i link relativi al DXVA basato su VMR9, EVR e relative differenze.

    Insomma io che non uso la GPU per grafica 3D (infatti ho solo integrate) le voglio usare per altro.

  • # 2
    Filippo
     scrive: 

    @ Alessio

    Per la precisione: CUDA e STREAM sono in effetti API proprietarie (rispettivamente Nvidia e ATi); DirectCompute è invece un componente delle DirectX 11, il cui obiettivo è (correggetemi se sbaglio) consentire un approccio alla computazione General Purpose su un hardware grafico astraendosi dai dettagli implementativi dell’hardware effettivamente presente.

    Ciao
    Filippo

  • # 3
    Giulio
     scrive: 

    Ciao Yoss, seguo sempre le tue rubriche, volevo farti innanzitutto i complimenti per la tua preparazione e il modo in cui illumini noi caproni :D
    Poi volevo approfittarne sciogliere un mio dubbio: da quanto ho capito RV770 utilizza un tesselletor “non standard” in quanto fuori specifiche dx11 (con hull e domain via shader) e Fermi sembra ricalcare questa strada.
    In questo modo non potrebbe incappare negli stessi problemi che non permettono a RV770 di utilizzare il tessellator con le dx11?
    Non voglio dire che Fermi non sarà dx11, piuttosto come mai l’approccio “non standard” di RV770 non vada bene e questo si.
    Grazie :)

  • # 4
    n0v0
     scrive: 

    non ci ho capito NIENTE !

    ma non è colpa dell’ autore ;-) Questo va un bel po’ oltre i limiti dell’ informatico per hobby quale io sono..

    Il succo, in definitiva, è sempre quello di come far girare su GPU le operazioni pensate per CPU?

  • # 5
    yossarian (Autore del post)
     scrive: 

    @ Giulio

    domanda legittima ma frutto di un enorme equivoco. A suo tempo si disse che RV770 non era dx11 compliant per la diversa implementazione del tessellatore. Di fatto non è così. Le dx11 prevedono che il tessellator sia, per così dire, “istruito” tramite funzioni di tipo progrmmabile sul da farsi. Si è pensato, perciò, a due stadi, hull e domain shader per svolgere questa funzione. Di fatto, però, l’implementazione con vertex shader e geometry shader che emulano hull e domain shader, rispettivamente, non rende i chip incompatibili con le DX11. Dal momento in cui la gpu riceve una chiamata a hull o domain shader, il driver la dirotta verso vertex o geometry shader sostituendola con un’istruzione adatta a questo tipo di unità.
    Questo vale su fermi quanto su RV770

  • # 6
    yossarian (Autore del post)
     scrive: 

    @ n0v0

    l’articolo si occupa di fare un confronto tra l’implementazione di alcune funzionalità facendo uso di unità dedicate e quella che fa uso di unità generiche. Quello di cui parli, ossia il tentativo di far girare codice da cpu su gpu, può essere una conseguenza dell’operazione di sostituzione di fixed function con unità programmabili. Nel caso di Intel, addirittura si parte dall’architettura di base di una cpu (per l’esattezza un Pentium I) per arrivare, introducendo unità funzionali tipiche di una gpu ocme,ad esempio, le TMU e un’unità vettoriale per ogni core del chip, che svolga operazioni di shading, rasterizzzione, ecc, a creare una gpu su cui giri, ovviamente, codice da cpu.

  • # 7
    michele
     scrive: 

    qouto giuglio…mi viene curioso capire dove gestiscono la differenza via driver o hardware?
    sennò anche per assurdo su xenos sarebbe possibile fare tessellation…..

  • # 8
    Giulio
     scrive: 

    Ok, grazie del chiarimento :)
    Quindi che RV770 non utilizzi il suo tessellator (nel bench Heaven ad es.) è dato dal fatto che quella funzione è stata prevista esclusivamente nel path dx11? Perché di fatto, se non conta che hull e domain siano emulati il “vecchio” tessellator di AMD potrebbe essere usato senza problemi giusto?

  • # 9
    yossarian (Autore del post)
     scrive: 

    @ michele
    togli anche quel “per assurdo”; xenos può fare tessellation anche se il tessellator presente non è uguale a quello di RV770 e xenos non ha la possibilità di fare geometry shading.

    Il modo in cui si fa tessellation è il seguente:
    il chip riceve informazioni sulla superficie da tessellare e sulla distanza dall’osservatore (e quindi sul dettaglio da riprodurre).
    Preleva della patch dal vertex buffer da ognuna delle quali ricava un n triangoli; calcola il LoD, e, quindi, l’entità delle operazioni di tessellation,effettua un cambio di coordinate per facilitare le operazioni, calcola la deformazione della patch e quindi il nuovo posizionamneto dei vertici esistenti. Passa tutto al tessellator vero e proprio che esegue l’operazione di aggiunta dei vertici e genera un set di nuove coordinate (u,v) per ciascun vertice. L’output del tessellator è composto da vertici che vangono passati al successivo stadio che, in base alle coordinate dei vertici e al tipo di superficie da riprodurre, controlla che tutto sia stato eseguito correttamente e si occupa, all’occorrenza, delle operazioni di displacement mapping.
    La prima parte delle operazioni (che in dx11 è previsto sia svolta dagli hull shader) comprende una serie di rotazioni e traslazioni tramite matrici e può essere eseguita dai vertex shader (anche se, non essendo hw dedicato, il numero di cicli impiegato per ogni operazione sarà superiore); l’ultima parte (a carico dei domain shader), quella di controllo, può essere ancora a carico dei vertex shader o, meglio ancora dei geometry shader.
    Quello che il driver deve fare è semplicemente intercettare una chiamata agli hull shader o ai domain shader e convertirla in una chiamata per i vertex shader e, quindi, sostituire, se necessario, laparte di codice relativa con una più “digeribile” per le unità a cui è destinata

  • # 10
    yossarian (Autore del post)
     scrive: 

    @ Giulio

    esatto; se il bench contiene una chiamata esplicita aglu hull shader, ad esmepio, e nei driver non è inserita una preephole optimization che intercetti la chiamata e la trasformi in una per i vertex shader, la tessellation non funziona.

  • # 11
    Giulio
     scrive: 

    Quindi ricapitolando (e concludendo, per la tua gioia :D):
    Fermi = DX11, Tessellator custom ed emulazione di hull e domain. Nessuna incompatibilità.
    RV870 = DX11, Tessellator secondo specifiche. Nessuna incompatibilità.
    RV770 = DX10.1, Tessellator custom ed emulazione di hull e domain.
    Incompatibilità per via dell’implementazione della feature nel path dx11.
    Spero sia tutto giusto, grazie :D

  • # 12
    yossarian (Autore del post)
     scrive: 

    fermi e rv770 hanno un’implementazione simile; neppure fermi ha hull e domain shader ma emula tutto tramite vertex e geometry shader.
    La differenza sta nel fatto che i driver nVIDIA per fermi contengono la “pezza” che permette di far funzionare il tessellator anche con chiamate ad hull e domain shader mentre ATi, avendo la serie 5000 dotata di quelle unità, non ha inserito questo tipo di ottimizzazione. Per cui sulla serie 4000 il tessellator non funziona (ma funzionerebbe con un’ottimizzazione analoga a quella usata da nVIDIA).
    Per le dx11 non è importante che hull e domain shader siano fisicamente presenti, l’importante è che il loro compito sia svolto da qualcuno (in pratica aggiungono solo due stadi dedicati ad un blocco che prima faceva le stesse cose facendone a meno).
    Ad essere pignoli, l’unico dx11 che rispetta formalmente le specifiche dx11 è quello della serie 5000 di ATi

  • # 13
    CountDown_0
     scrive: 

    Come sempre un ottimo articolo, complimenti! ;-)

  • # 14
    Al
     scrive: 

    Michael Abrash? … quello delle ottimizzazioni del motore del primo Quake?

    Non era andato alla Microsoft?

  • # 15
    Nessuno
     scrive: 

    Ciao,
    ho letto l’articolo con molto interesse.
    Volevo chiedere una cosa un po’ particolare che hai accennato: l’impatto della distribuzione nel Fermi delle operazioni geometriche. A parte essere fixed-function o usare gli shader, l’idea di distribuire questo tipo di calcoli all’interno degli SM non aiuta l’architettura a scalare in maniera migliore?
    Intendo, in una configurazione SLI o CF, come possono i tue tesselator negli RV870 collaborare per velocizzare il calcolo?
    Mentre 2 GF100 potrebbero suddividere le operazioni sui rispettivi SM e ottenere effettivamente una potenza di elaborazione doppia.
    Oppure anche la soluzione su RV870 può scalare, o viceversa, quella su Fermi non scala come ho supposto?

    Grazie per una eventuale risposta.

  • # 16
    yossarian (Autore del post)
     scrive: 

    @ Nessuno

    ottima domanda; non ho commantato la cosa in questo articolo perchè sarà uno degli argomenti di un altro post in cui intendo esaminare alcuni aspetti dell’architettura di fermi, però cerco di risponderti in maniera sintatica.
    Il tessellator proposto da ATi non scala, nel senso che, qualunque sia la richiesta di potenza non può andare oltre ciò che l’hardware dedicato èpresente può permettergli. Questo significa che può risultare sottodimensionato in allcuni casi e sovradimensionato in altri. Nella prima situazione non è in grado di erogare più potenza, nel secondo c’è una parte di silicio che rimane inutilizzata. Questo vale epr il singolo chip; in configurazione dual la distribuzione dei carichi di lavoro delle operazioni di tessellation è identica a quella delle restanti operazioni, quindi, tra le varie istruzioni che i due chip ricevono, ci sono anche quelle relative ai due tessellator. In modalità AFR ogni gpu agisce su un frame per cui anche il rispettivo tessellator si occuperà della geometria di quel frame
    La scalabilità del tessellator di fermi è apprezzabile soprattutto sul singolo chip. In teoria, fermi potrebbe dedicare l’intero shader core alle operazioni di hull e domain shading ed avere una potenza teorica disponibile enorme per le operazioni di tessellation. Oppure, al contrario, potrebbe usare uno solo dei 16 polymorph engine, coadiuvato da un gruppo di 32 o anche solo 16 alu che fanno da hull e domain shader.
    Questo rientra tra i vantaggi dell’utilizzo di hardware generico che può svolgere quei calcoli che, al momento, si rendono necessari. C’è il rovescoi della medaglia, però: tutte le risorse che fermi utilizza per le operazioni di tessellation sono sottratte ad altri tipi di elaborazione (una gpu lavora contemporaneamente su vari tipi di dati e può trovarsi ad eseguire, ad esempio, operazioni di pixel shading su alcuni degli SP e operazioni geometriche su altri). I chip nVIDIA, grazie all’architettura superscalare, risultano già piuttosto efficienti come rapporto tra numero di alu presenti e numero di alu attive ciclo per ciclo; questo, paradossalmente, nell’ottica di distrarre unità di calcolo da un task per dedicarle ad un altro, può risultare controproducente.
    Quindi, se da un lato hai hardware dedicato che può fare solo tessellation e, quando questa feature è inutilizzata, lo stesso vale per le unità che se ne devono occupare, dall’altro c’è da vedere come bilanciare al meglio, di volta in volta, le operazioni delle alu generiche per non penalizzare troppo un tipo di elaborazione a vantaggio di un’altra

    @ Al

    si, è lui: ha lavorato prima in ID su quake, poi in MS allo sviluppo di win NT e da qualche tempo lavora in Intel allo sviluppo del SW per larrabee.

  • # 17
    UltimateBou
     scrive: 

    domande x YOSS:

    1) un gioco DX11 in piena specifica che utilizza il tessellator secondo direttive microsoft trae vantaggi dall’implementazione NVIDIA o funziona in modo ufficiale per come funziona sulla serie 5000 ATI ?

    2) NVIDIA ha solo questo tessellator “custom” oppure ha anche quello dx11 per come ha ATI con la serie 5000?

    3) Il tessellator “secondo microsoft” è una prerogativa per dichiarare una scheda pienamente compatibile DX11, aprendo così uno scenario sulla compatibilità piena e/o ufficiale di Fermi con DX11 ?

    4) sottrarre potenza di calcolo (un pò come per physyx) alla gpu per delegarla al tessellator, potrebbe impattare sulle prestazioni complessive, rendendo vano il vantaggio?

    5) cosa dobbiamo aspettarci in quanto a performance del tessellator su un gioco DX11 che non prevede ottimizzazioni in tal senso per l’implementazione nvidia?

  • # 18
    yossarian (Autore del post)
     scrive: 

    @ UltimateBou

    1) la seconda che hai detto; nVIDIA deve fare un’operazione di ottimizzazione tramite driver per adattarlo alla propria implementazione.
    2) nVIDIA ha solo questo tessellator
    3)secondo MS la prerogativa è che il tessellator funzioni in una certa maniera. La sua corretta implementazione “fisica” è quella mostrata da ATi con la serie 5000. C’è da aggiungere che sia fermi, sia, ad esempio, RV770, facendo un’operazione di intercettazione delle chiamte e, se necessario, sostituzione o adattamento delle istruzioni, possono eseguire le operazioni di tessellation seguendo le specifiche dettate da MS. Quindi, fisicamente, il tessellator di fermi non è dx11 ma può funzionare come un tessellator dx11 (motivo per cui sostenevo sul forum di HWUpgrade che il tessellator non è una discriminante per stabilire se un chip è dx11 o meno e che quello di RV770 poteva fare le stesse cose di quello previsto dalle dx11. Pensa che larrabee non dovrebbe avere neppure l’unità dedicata alla tessllation vera e propria eppure potrà emulare alla perfezione un tessellator dx11)
    4) sicuramente un impatto sulle prestazioni ci sarà. Un conto è avere unità dedicate a quella sola operaione, un altro è avere hardware generico che deve occuparsi anche di altro. Come per physx, quando si usa sia grafica che fisica in maniera “pesante” le prestazioni crollano, lo stesso potrebbe accadeere con l’implementazione del tessellator fatta da nVIDIA. Per questo sarà necessario un lavoro di ottimizzazione del bilanciamento dei carichi di lavoro molto oculato. Sarà interessante vedere come il thread processor è stato programmato per gestire queste situazioni. Un vantaggio di fermi rispetto a gt200 è che ha una granularità più fine nella gestione dei thread e che può gestire più kernel (inteso come batch di warp) in contemporanea.
    5) che nVIDIA provveda alle ottimizzazioni del caso: i driver devono intercettare le chiamate e hull e domain shader e trasformarle in chiamate per vertex e geometry shader.
    Per quanto detto prima a proposito del bilanciamento del workload, mi aspetto su fermi prestazioni variabili al variare della complessità della grafica e del peso delle operazioni di tessllation mentre su RV870 la variabilità sarà dovuta al rapporto tra richieste del software (quanto c’è da tessellare) e potenza massima disponibile per le operazioni di tessellation (che è quella data dall’unità dedicata). Quindi, per ATi si può considerare la presenza di una “soglia” per nVIDIA le prestaioni possono oscillare in maniera meno prevedibile.

  • # 19
    UltimateBou
     scrive: 

    grazie delle risposte! certo, da incompetente in materia programmazione la situazione mi sembra per lo meno “particolare”

    se il tessellator nvidia e quello ati serie 4000, funzionano “orientativamente” allo stesso modo e necessitano di un “passaggio in più” (intercettazione delle chiamata e traduzione della stessa), questo avverrebbe per come hai detto dai driver (similarmente per come accade aggiungendo un profilo SLI o CROSSFIRE per supportare tale tecnologia se non ho capito male): dunque mi chiedo.. dovremmo aspettarci per giochi non specificatamente ottimizzati, una release nuova dei forceware con una release note tipo “aggiunto profilo supporto tessellatore sul gioco X” ? O si “comprano” l’ottimizzazione prima :P ? (e forse questa ha una risposta scontata…)

    C’è un motivo logico che ha portato nvidia a fare questa scelta? Sbattersi poco a fare un chip dedicato come per ATI (di contro lato driver dovranno quindi sbattersi di più), visto che già Fermi non scherza per complessità/consumo/calore potrebbe essere un motivo? O magari la “mania” di usare questi cores cuda come per physx…?

    in un gioco che supporta physx e tessellatore nvidia, fermi si impicca perchè non sa a chi deve dare prima conte e ragione nei calcoli da svolgere, oltre al normale renderding? :D

  • # 20
    yossarian (Autore del post)
     scrive: 

    @ UltimateBou

    1) in effetti potrebbero non avvenire nessuno dei due eventi prospettati da te.
    Hull e domain shader hanno un set di call di tipo standard. Basta inserire un preephole (una specie di finestra) che, una volta tradotto il codice in linguaggio bibario, intercetti queste chiamate e le sostituisca con analoghe chiamate a vertex e geometry shader. Lo si fa una tantum e vale per sempre :D

    2) la possibilità di avere una maggor potenza di calcolo geometrico, se necessario, senza dedicare troppo HW ad esso. L’alternativa sarebbe stata quella di inserire tante unità di tessellation dedicate se si voleva avere la possibilità di modulare la potenza di calcolo. In effetti è ciò che è stato fatto, ma limitatamente a quelle unità la cui sostituzione diventava anti economica, ossia quelle fixed function che avrebbero richiesto troppi cicli alle unità generiche. Quindi tra il dotare il chip di unità FF dedicate o l’aumentare in proporzione le unità generiche per non impattare troppo sule prestazioni si è scalta la seconda strada (come ha fatto INtel con le unità di texture sampling in larrabee)
    3) si dovrà vedere sul campo come si comporterà; al momento non è stato mostrato praticamente niente di concreto da cui trarre indicazioni sulle prestazioni di fermi

  • # 21
    Nessuno
     scrive: 

    Ciao,
    ritorno sulla questione della distribuzione del carico di lavoro tra l’implementazione ATI e quella nvidia.
    Non so come funzioni effettivamente l’unità di tesselation, ma l’unità FF di ATI dovrebbe poter lavorare su un oggetto solo, mentre quella nvidia su più oggetti contemporaneamente.
    In questo caso, il fatto che l’unita FF di ATI sta “a monte” di tutti gli shader è possibile per questa elaborare più oggetti serialmente e fare i calcoli successivi negli shader in maniera parallela o deve necessariamente attendere che i risultati di un calcolo di tesselamento precedente sia completato?

  • # 22
    Cesare Di Mauro
     scrive: 

    Non so che tipo di operazioni vengano svolte da hull e domain shader, ma se le unità “unificate” dedicate all’elaborazione di pixel, vertici, geometria e fisica fanno più o meno le stesse cose, credo che l’approccio migliore possa rivelarsi quello di utilizzare le stesse unità anche per questo lavoro.

    Quindi niente unità fixed function, ma un bel peephole optimizer che in una sola passata intercetta le loro istruzioni e le converta in equivalenti operazioni.

    Il vantaggio sarebbe lo stesso del passo che ha portato all’unificazione di pixel e vertex shader: avere le stesse unità per elaborare queste richieste, in modo da sfruttarle al massimo a prescindere dal tipo di operazioni elaborate.

    Il vantaggio ulteriore sarebbe quello di poter controllare via software questa conversione, eventualmente ottimizzando ad hoc per particolari giochi, e in generale la qualità del peepholer potrebbe migliorare intrinsecamente se si scoprono nuove ottimizzazioni.

    Ovviamente sono solo ipotesi. Parlo da profano perché non conosco né l’architettura delle unità di calcolo né le operazioni che vengono svolte da questi nuovi shader utilizzati per la tessellation.

  • # 23
    Nessuno
     scrive: 

    Ciao,
    mi scuso per come ho postato il precedente commento, ma ho problemi di linea oggi e ho postato prima di concludere e di aggiungere i dovuti ringraziamenti per le delucidazioni che ci dai.

    Scusatemi.

  • # 24
    yossarian (Autore del post)
     scrive: 

    @ Nessuno e Cesare

    Dipende dalle dimensioni dell’oggetto. Un’unità di tessellation lavora su una patch per volta. Questa superficie è formata da un certo numero di triangoli e contiene, quindi il relativo numero di vertici. Fermi ha l’unità che vertex fetch distribuita tra i 16 SP mnetre RV870 ne ha una unica. Questo significa che fermi può fare più operazioni di vertex fetching in parallelo mentre RV870 uno per volta. E questo è un vantaggio per fermi anche qualora le singole patch che carica siano di dimensioni molto minori di eulla di RV870.
    A questo punto dobbiamo, però, fare una precisazione. Solo il tessellator è FF, hull e domain shader sono programmabili esattamente come pixel, vertex e geometry shader.
    Gli hull shader prendono la patch, fanno un cambio di base, decidonmo come e quanto di deve tessellare e trasmettono le istruzioni al tessellator e i domain shader controllano che il lavoro sia stato eseguito correttamente e si occupano di fare displacement mapping. Questo vale sia su ATi che su nVIDIA. Questo significa che, ad esempio, su RV870, una volta che è stata tessellata la prima patch e passata ai vertex shader, mentre questi iniziano a lavorare il tessellator (hull e domain shader compresi) inizia a lavorare sulla successiva patch. Su fermi, dopo che la prima patch di ogni polymorph engine è stata tessellata, l’unità di vertex fetching carica la seconda patch che viene inviata ai vertex shader che fungono da hull shader (i quali vertex shader potrebbero, nel frattempo, aver ricevuto i dati della precedente operazione di tessellation e, quindi, si trovano a dover lavorare su entrambi). In seguito, passano i risultati dell’elaborazione al tessellator vero e proprio (che è anche in fermi di tipo ff) nel polymorph engine che crea i nuovi vertici e rispedisce il tutto allo shader core (GS che però sono gli stessi che fanno VS e PS e, suppongo, anche texture filtering).
    Quindi, anche in fermi le operazioni avvenogno serialmente; le differenze sono che: in fermi si possono avere fino a 16 operazioni seriali dello stesso tipo. In fermi ci può essere una sovrapposizione dei compiti tra HS, DS, VS, GS e PS, nonchè TFU (texture filter unit). Quindi, vero che sono tente unità, ma hano anche un enorme carico di lavoro (6 differenti tipi di task contro i 4 dei chip AMD, senza tener conto anche dell’eventuale utilizzo di physx).

    @ solo Cesare

    si, il vantaggio può essere lo stesso che ha portato all’unificazione di VS e PS ma si deve valutare se i tempi sono maturi (ovvero se c’è sufficiente potenza di calcolo e che, per eliminare un potenziale collo di bottiglia, non se no introducano di altri).
    Comunque, come detto, anche hulle domain shader sono programmabili e l’unità di tessellation è FF anche su fermi (tutto il polymorph engine ed il raster engine sono composti da unità FF)

  • # 25
    TheFoggy
     scrive: 

    ottimo articolo, yossarian, come sempre!
    Avrei una domanda su come si effettua a livello logico la tessellation:
    gli Hull Shader “sistemano” la patch, ponendola in posizione neutra, fondamentalmente, e fin qui, tutto ok. decidono anche SE e QUANTO..si basano solo sul LoD? oppure posso inviargli delle specifiche aggiuntive?
    Il tessallator, come fa a sapere in quanti sottopoligoni suddividere una patch? Ho visto esempi in cui (LoD disabilitato..serviva per fare testing!) un modello (tra l’altro..rapporto modello/patch? Oppure con patch intendi “la parte di geometria che riesco a caricare”? mi sfuggono questi paio di termini) era suddiviso in alcuni punti, in molti poligoni e in altri in molti meno..eppure si trovavano alla stessa distanza ed avevano (originariamente) la stessa normale..
    La displacement map, può essere utile per capire che operazioni eseguire? Più devo “spostare”, più divido? E le informazioni sulla direzione dello spostamento, dove le trovo?
    (in unigine si vede un drago che da piatto, si ritrova ad avere spuntoni non proprio in linea con la normale del poligono originario..chi gestisce quest’ulteriore displacement?)

    Grazie!

  • # 26
    yossarian (Autore del post)
     scrive: 

    @ TheFoggy

    ciao, vediamo se riesco a soddisfare la tua curiosità senza anticipare troppi argomenti di un successivo articolo (che ci sarà sicuramente, visto l’interese che sta suscitando questa feature) :D

    Per patch intendo, probabilmente, quello che tu hai definito modello, ossia la superficie che viene caricata e su cui si lavora.
    Gli hull shader ricevono la patch dai vertex shader che hanno definito i control point e stabiliscono, in base al LoD, alla funzione utilizzata per definire la curva e, anche, ad eventuali specifiche aggiuntive, come, eventualmente, rimaneggiare i control point e quanti triangoli ricavare da quella specifica superficie.
    Quindi passano tutto al tessellator. Le indicazioni sulla displaced map possono anche essere utilizzate per ricavare dati sulla tessellazione se le due cose sono correlate e se un eventuale spostamento dei vertici necessita di aggiustamenti eventuali.
    Hai fatto l’esempio dell’unigine; non ho ben presente il passaggio di cui parli, però l’effetto di spostamento di vertici rispetto ala normale originale può dipendere dal fatto che in fase di tessellazion le patch subiscono delle deformazioni e le posizioni dei vertici pososno essere modificate. Quindi l’effetto cha hai notato potrebbe essere frutto di una deformazione della superficie con relativo cambio di orientamento della normale in determinati punti e successiva operazione di displacement map.

  • # 27
    Ciano
     scrive: 

    Ottimo articolo e interessanti i commenti.
    Sai se vengono usate curve NURBS nei motori dei giochi per calcolare in che direzione (nuove coordinate) creare i nuovi triangoli nella fase di tessellation ?

  • # 28
    yossarian (Autore del post)
     scrive: 

    @ Ciano

    si le nurbs sono tra le curve utilizzate; ne parlerò in maniera più approfondita nell’articolo sulla tessellation

  • # 29
    Simone82
     scrive: 

    Volevo chiedere se l’autore farà il multitasking tra sensori e gpu sfruttando il calcolo gpgpu oppure no… xD

    Altro articolo perfetto imho, oramai mi sono abbonato a questa serie… A quando il prossimo?

  • # 30
    yossarian (Autore del post)
     scrive: 

    @ Simone82

    l’ideale sarebbe
    multitasking come una cpu
    multithreading come una gpu
    criterio di scelta settimanale assimilabile a quello dell’arbiter di un memory controller: la prima cosa che ti insegnano quando studi le architetture del MC (ma anche al corso degli arbitri a Coverciano :D), è che l’arbitro non deve essere imparziale.

  • # 31
    StreamX
     scrive: 

    La definizione dei punti luce in una scena 3d di quanto fa decadere le performance ?
    Pesa sui vertex shader aggravando i limiti del setup poligonale ?

  • # 32
    yossarian (Autore del post)
     scrive: 

    @ StreamX

    si; ti linko un paio di recensioni di quelle in cui ancora si usava inserire test sintetici epr valutare le diverse funzionalità di una gpu

    http://www.hwupgrade.it/articoli/stampa/skvideo/638/

    http://www.lithium.it/editoriale.asp?id=6&p=6

    le review sono un po’ datate, ma trovi delle tabelle da cui è possibile rendersi conto dell’impatto che la scelta di più punti luce ha sul setup poligonale.
    Purtroppo le attuali review non inseriscono più test di questa natura e i bench sintetici si limitano agli inutili punteggi finali dei vari 3dmark e simili.

  • # 33
    StreamX
     scrive: 

    Chiedevo proprio perchè ricordavo le vecchie recensioni.

    Puoi chiarirmi un punto,
    Le sorgenti di luce inficiano il setup-triangle o pesano solo sulle ALU (vertex shader) ?

  • # 34
    yossarian (Autore del post)
     scrive: 

    @ StreamX

    quella che pesa di più è la componente di tipo specular; in ogni caso, il peso maggiore è a carico delle alu e, in alcuni casi, delle texture unit (il texture mapping è usato per alcuni effetti di illuminazione di tipo speculare)

Scrivi un commento!

Aggiungi il commento, oppure trackback dal tuo sito.

I commenti inseriti dai lettori di AppuntiDigitali non sono oggetto di moderazione preventiva, ma solo di eventuale filtro antispam. Qualora si ravvisi un contenuto non consono (offensivo o diffamatorio) si prega di contattare l'amministrazione di Appunti Digitali all'indirizzo info@appuntidigitali.it, specificando quale sia il commento in oggetto.