Recensioni » Schede video » Sapphire Radeon HD X2900XT 512Mb


Command Processor (CP), Setup Engine e U.T.D.P.



Command Processor (CP)
Il Command Processor è un vero e proprio processore che ha la possibilità di accedere indipendentemente alla memoria di sistema e fare calcoli matematici ed elaborazioni.
È posizionato all’entrata dei dati e svolge soprattutto operazioni per diminuire il carico di lavoro svolto dai Driver di sistema (Carico CPU) avendo la possibilità di scaricare microcode e eseguire istruzioni vere e proprie. All’atto pratico il command processor all’entrata dei dati esegue certe operazioni e valida tutti i dati in transito sincronizzandone la successione e rilevando gli stati delle operazioni che sono in svolgimento.

Questo quindi da la possibilità di avere sempre un flusso di dati continuo e senza accavallare le operazioni che devono essere svolte sgravando da questo compito il lato Driver che fa affidamento sulla CPU. Cosi facendo si riduce la parte di lavoro che la CPU deve svolgere per la validazione dei dati da mandare alla scheda video diminuendo quindi la limitazione delle performance grafiche per colpa della CPU di sistema, il cosiddetto “CPU limited”.

Il command processor è definito anche “Consapevole” in quanto all’arrivo dei dati controlla prima che cosa sta facendo la restante parte della GPU (Interpella l’Hardware per capire le operazioni in fase di svolgimento) in modo da sincronizzare i dati con il solo scopo di finire prima le operazioni che si stanno già svolgendo, mettendo quindi per primi in entrata i dati che servono per le operazioni già in corso, e quelle che devono ancora essere svolte in modo da massimizzare la velocità delle operazioni. AMD sostiene cosi di aver diminuito l’overhead, dato dal fatto che queste operazioni prima venivano svolte fuori dalla scheda video, in pratica rubando cicli alla CPU che diventava determinante nelle preformance della VGA stessa che doveva aspettare che la cpu validasse le istruzioni diventando cosi CPU limited.

Questo effetto lo si può vedere molto bene utilizzando VGA nVidia GeForce 8800 che sono molto potenti ma limitate dalla CPU che a seconda della frequenza di funzionamento aumenta o diminuisce le performance del sottosistema grafico in maniera molto marcata.

Setup Engine
Subito dopo il command processor si trova il Setup Engine che come si vede dal disegno prepara i dati dividendo e campionando tutto quello che poi andrà attraverso il Dispatch processor agli shader.
Al suo interno quindi troviamo degli assembler per vertex e geomtry shader e il programmable tasselletor.

Per semplificare la spiegazione il Setup Engine svolge tre operazioni che servono per preparare tutti quello che serve agli shader e a inviarglielo. Il Vertex Assembler serve per l’asseblaggio e la tassellazione dei comandi vertex, l’indirizzamento dei vertici da prelevare e l’ottenimento degli indici oltre a eseguire alcuni algoritmi associati agli indici vertex. Il vertex assembler indirizza cioè gli shader su che cosa fare e quali indici prelevare per primi secondo i dati elaborati dal setup engine. La parte geometry assembler sa in linea di massima le stesse cose che fa il vertex assembler prelevando e indirizzando però tutta la parte geometry per gli shader. Stesso identico discorso va fatto per la parte pixel che dopo le dovute operazioni vengono mandati a un interpolatore a sua volta collegato con l’Ultra-Threaded Dispatch processor.

Ultra Thread Dispatch Processor U.T.D.P.

Terminata la fase del setup engine troviamo l’Ultra Thread Dispatch Processor dal quale dipendono 2 cache dedicate rispettivamente a Shader Instruction Cache e Shader Constant Cache che fanno si che si possano avere sia shader di lunghezza illimitata in termini di istruzioni sia shader con un numeri illimitato di costanti. Per ogni unità SIMD sono presenti 2 unità Arbitrer che 2 unità Sequencer che permettono di effettuare 2 operazioni in parallelo per ogni SIMD per ogni ciclo di clock. Andiamo a vedere adesso più in dettaglio tutta la fase di arbitraggio e sequenza delle informazioni con particolare attenzione al discorso inerente alla virtualizzazione della cache e come va a funzionare poi il tutto.


  • Arbitri

Come si vede dall’immagine ogni gruppo di SIMD ha 2 arbitri dedicati. L’arbitro è stato introdotto da ATI gia con la realizzazione del progetto R500 Xenon e serve principalmente per garantire che in ogni istante tutti gli shader abbiano del lavoro da svolgere e che soprattutto stiano svolgendo le giuste cose e nella maniera più corretta, in modo tale da finire il prima possibile l’elaborazione dei dati assegnati. A livello pratico l’arbitro fa da tramite tra il setup engine, che contiene le tre code di dati Vertex Geometry e Pixel, e gli shader.

Quando uno slot finisce l’elaborazione che stava eseguendo manda un segnale di SLOT all’arbitro, che indica che lo shader è libero e può ricevere un altro dato da elaborare. A questo punto l’arbitro interpella il Setup Engine e sceglie dalle tre code quale sia l’istruzione più adatta per esser elaborata nel dato momento. Infatti l’arbitraggio non e fisso ma dinamico, cioè a seconda sia del carico lavoro che della quantità e il tipo di dati da elaborare decide tutte le sequenze da far fare ogni volta che si libera uno SLOT.

Una volta che i dati sono passati agli shader possono essere elaborati o essere messi da parte fino a che non li si può elaborare, infatti negli shader ci sono più thread in esecuzione, anche se solo 1 in elaborazione mentre gli altri sono sospesi. L’arbitro quindi decide anche che thread far elaborare e quali tenere ancora sospesi per massimizzare le performance e il “riempimento” di tutti gli shader. Adesso potrebbe sorgere una domanda: Perché usare 2 arbitri per ogni SIMD?

La risposta è molto semplice, mentre il primo arbitro etichetta ogni operazione in modo che gli shader sappiano con quale thread lavorare e quale lasciare in sospeso, il secondo serve per l’uso delle risorse di sistema da parte dei thread in elaborazione. Il secondo arbitro quindi non fa altro che mettere in coda tutti i thread che devono usare la stessa risorsa, un po’ come quando si va a fare la spesa e si prende il numerino per il proprio turno e ci si mette in coda ad aspettare fino a che non arriva il vostro turno!

Alla fine quindi ogni SIMD contiene sempre 2 thread, uno in esecuzione e uno in pausa, comandati tramite i due arbitri. Questo comporta che in ogni singolo istante tutti gli stream processor siano occupati a fare un elaborazione e quindi non passino dei cicli di clock senza operare.
Il flusso quindi passa a cicli alterni all’interno dei SIMD in questo modo : Clock 1 – thread 1 , clock2 – thread 2, clock 3 – thread 1, clock 4 – thread 2 e cosi via finche il thread non è completato.
Partendo dal Setup engine quindi ci son varie fasi da seguire

  • Il setup engine crea i thread e li raggruppa in blocchi da 64 (ogni blocco contiene 64 oggetti creati dagli assembler e dallo scan converter)
  • I dati vengono inviati all’ultra thread dispatch processor che tramite gli arbitri li analizza e li mette nella giusta sequenza per massimizzare al massimo il lavoro per ciclo di clock arbitrando sequenza dei thread e accesso alle varie risorse
  • I dati accedono al blocco di stream processor (SIMD)

All’interno di R600 troviamo 4 SIMD quindi ci saranno 8 arbitri adibiti, in gruppi di 2, all’arbitraggio dei thread e delle risorse inerenti al SIMD a cui fanno capo. Tutto questo arbitraggio, che visto cosi potrebbe essere molto complicato e laborioso, serve per ridurre il più possibile le latenze e sfruttare sempre al 100% le risorse interne al chip.

  • Sequencing

Associato a ogni arbitro c’è un Sequencing, 2 per ogni SIMD in un totale di 8 in tutto il chip. A cosa serve questo componente? Torniamo all’esempio fatto prima con l’arbitraggio riguardante le file al supermercato. L’arbitro assegna a ogni thread un “numero” e lo mette in coda ad aspettare il proprio turno cosi come fate voi al supermercato, prendete il numerino e aspettate il vostro turno. Il sequencing non fa altro che chiamare il numero quando è arrivato il vostro turno e ci sono quindi o stream pronti a elaborare i dati oppure è stata accolta la richiesta per usare una determinata risorsa dal thread in esecuzione. Quindi il thread svolge un elaborazione e poi, se non può andare avanti o la risorsa è occupata, viene sospeso e viene chiamato un altro thread.
Arrivati a questo punto sorge un problema di spazio, visto che nell’uso normale nella crazione di una scena 3D ci saranno milioni di thread che verranno sospesi per ogni ciclo di clock e devono essere archiviati da qualche parte in attesa di essere richiamati.

AMD ha ovviato al problema creando una cache virtualizzata che permette di immagazzinare un numero illimitato di thread.

  • Virtualizzazione Cache U.T.D.P.

Con R600, un approccio fatto con arbitraggi e sequencing di thread, richiede uno spazio molto grande in cache per avere la possibilità di immagazzinare i thread che sono sospesi durante i vari cicli di clock. Ecco che AMD quindi ha virtualizzato tutte le cache interne a R600 in modo tale da “TEORICAMENTE e VIRTUALMENTE” immagazzinare un numero illimitato di thread.
Ovviamente nella realtà la cache ha uno spazio fisico prestabilito dato da 232 istruzioni word che corrispondono all’incirca a 4Gb di dati shader, quindi alla fine tutto questo spazio può essere pensato come illimitato.

  • Funzionamento

AMD ha adottato quindi un funzionamento diverso da quello abituale, cioè elaborando un thread per volta, mettendo in campo per ogni ciclo di clock un numero elevato di thread che vengono continuamente elaborati e sospesi fino a che non finiscono tutte le elaborazioni richieste. Questo serve per mascherare le latenze che si andrebbero a creare svolgendo un thread per volta.
Nel caso di un thread che chieda un accesso in memoria deve prima aspettare che ci sia un riscontro che il dato ci sia in cache aspettando quindi dei cicli di clock senza lavorare, che possono allungarsi se il dato richiesto si trova al di fuori della scheda video magari in RAM di sistema. L’idea quindi consiste nel sospendere il thread in esecuzione intanto che si aspetta la risposta dalla memoria e si manda avanti un altro thread.

Questo si traduce in un uso sempre massimo delle risorse mascherando le latenze portandosi avanti il lavoro di altri thread. Per fare ciò si ha bisogno di un volume di dati molto elevato che viene fornito dal bus di sistema che essendo in questa versione, X2900XT, di 512bit con memorie GDDR3 si traduce in una banda passante teorica di 105Gb/s e sarà portato a 160Gb/s con l’adozione nel prossimo futuro delle memorie GDDR4. A questo punto entra in gioco quanto detto sull’arbitraggio, vista la mole di dati e client che vengono a usare il bus di memoria, serve organizzare i dati in modo che le operazioni richieste siano messe nella giusta sequenza per produrre poi il risultato finale.

A conti fatti quindi un processore grafico come R600 ha la possibilità di elaborare in parallelo una moltitudine di dati pari a decine di migliaia di thread che, a seconda di cosa chiedono o devono fare, vengono elaborati o sospesi in modo da mascherare molto bene le latenze che servono fisicamente per ogni singolo thread fino al suo completamento.







   Autore:
   Tommaso Morosini
   Categoria:
   RSS Schede video
   Data pubblicazione:
   23/06/2007

© Copyright 2006-2008 Hardware Station
E' vietata la riproduzione, anche solo in parte, dei contenuti e della grafica senza autorizzazione del webmaster
Responsabile: Alex Skerlavaj