UltraSPARC III
# UltraSPARC III

L'UltraSPARC III è un microprocessore 600-900 MHz sviluppato da Sun Microsystems e fabbricato da Texas Instruments. Fa parte della famiglia dei microprocessori UltraSPARC che implementa la versione 9 dell'architettura SPARC (Modello di architettura RISC) insieme a UltraSPARC I, UltraSPARC II e UltraSPARC IV.

## Storia

Fu presentato al Microprocessor Forum del '97; la data di pubblicazione doveva essere nel 1999 ma, a causa della concorrenza con Digital Equipment Corporation 21.264 Alpha e Intel Itanium, venne rimandata al 2001. Vi è stato comunque assegnato un premio Analysts 'Choice Award per il miglior Server / Workstation

### La rivoluzione UltraSPARC

Fin dalla prima versione dell'UltraSPARC (L'UltraSPARC I, 1995) vi fu una forte rottura con i tipi di architettura precedenti; in effetti queste ultime erano progettate per elaborare dati alfanumerici ed eseguire programmi per il trattamento testi e fogli di calcolo, mentre l'UltraSPARC era in grado di gestire immagini, audio, video e dati multimediali. Tra le più importanti innovazioni vi fu l'aggiunta di 23 nuove istruzioni, alcune per compattare e scompattare pixel da parole di 64 bit, altre per ruotare e ridimensionare immagini e per comprimere e decomprimere video in tempo reale. Queste istruzioni vennero chiamate VIS (Visual Istruction Set, Insieme di Istruzioni Multimediali). Inoltre nonostante tutte le versioni dell'UltraSPARC hanno un'architettura interamente a 64 bit con indirizzi e registri a 64 bit, la serie offre una considerevole retrocompatibilità con l'architettura SPARC version 8 (che è a 32 bit), essendo in grado di gestire operandi a 32 bit ed eseguire software programmato per SPARC a 32 bit senza bisogno di modifiche. La differenza principale fra i diversi modelli di UltraSPARC era la frequenza del clock anche se ogni nuova versione vennero aggiunte importanti innovazioni.

## Microarchitettura UltraSPARC

Dal punto di vista software i vari modelli della serie UltraSPARC sono molto simili e le differenze riguardano principalmente prezzo e prestazioni; dal punto di vista hardware sono invece notevolmente diverse a livello di microarchitettura. Analizzeremo in maniera specifica il processore UltraSPARC III Cu ('Cu' indica il simbolo chimico del rame che è utilizzato al posto dell'alluminio per i collegamenti all'interno del chip, garantendo maggiore velocità e realizzazione di collegamenti più fini). La maggior parte delle istruzioni dell'UltraSPARC sono di 4 byte; è dotato di un'unità di rifornimento delle istruzioni (IFU) che prepara fino a 4 istruzioni ogni ciclo per l'esecuzione, tranne nel caso in cui si verifica un fallimento della cache in quanto ne viene emesso un numero minore. Per gestire salti condizionati questo dispositivo può consultare una tabella dei salti; all'interno di essa troviamo un bit di validità, l'indirizzo del salto e 2 bit per cercare di predire il salto in maniera corretta. Uno di questi bit tiene traccia dell'ultimo salto effettuato da quell'indirizzo e l'altro predice il salto da effettuare. La struttura di questa tabella permette di modificare la predizione soltanto dopo che 2 previsioni consecutive si rivelano errate. Le istruzioni dopo essere state prelevate vengono inviate in un buffer a 16 posizioni che regolarizza il flusso di istruzioni entranti nella pipeline e le invia ad altri 3 dispositivi: l'unità di esecuzioni per gli interi, l'unità di esecuzione in virgola mobile e l'unità di caricamento e memorizzazione. All'interno dell'unità di esecuzioni degli interi sono presenti 2 ALU, i registri ISA e alcuni registri di lavoro. L'unità in virgola mobile contiene 32 registri e 3 ALU distinte, ognuna delle quali effettua un'operazione differente (rispettivamente addizione/sottrazione, moltiplicazione e divisione) ed esegue anche istruzioni grafiche. L'unità di caricamento e memorizzazione si occupa di gestire il flusso dati proveniente dalla memoria ed utilizza 3 cache differenti: la cache dei dati (cache associativa a 4 vie di livello 1 da 64KB e linee di 32 byte), la cache di prefetch (da 2KB realizzata in quanto l'architettura ISA della macchina permette di prelevare parole di dati prima ancora che siano necessari attraverso un compilatore che carica in anticipo all'interno della cache una data parola che potrebbe essere necessaria), la cache di scrittura (da 2 KB usata per migliorare le prestazioni raggruppando al suo interno i dati da scrivere in memoria e inviandoli a una cache di secondo livello esterna alla CPU). Il chip contiene al suo interno tre componenti logici che servono a controllare l'accesso alla memoria: l'interfaccia del sistema, il controllore della cache L2 e il controllore della memoria. L'interfaccia del sistema collega il chip alla memoria tramite un bus di 128 bit, essa è stata progettata in modo da permettere la connessione di più UltraSPARC a una stessa memoria in modo da formare un multiprocessore. Il controllore della cache L2 permette di interfacciare il chip con la stessa (dimensioni variabili da 1.4 a 8 MB dipendente dalla dimensione della cache). Inoltre, l'UltraSPARC supporta una memoria virtuale con pagine da 8, 64, 512 KB e 4 MB, in grado di mappare indirizzi virtuali a 64 bit in indirizzi fisici a 43 bit; per ottimizzare il tutto sono presenti 3 tabelle chiamate TLB(Translation Lookaside Buffers) di cui una per gestire in modo flessibile le diverse dimensioni delle pagine e le altre due per effettuare la corrispondenza delle istruzioni.

## Pipeline

L'ultraSPARC III Cu dispone di una pipeline a 14 stadi.

* Lo stadio address generation si trova all'inizio della pipeline ed è il punto dove si determina l'indirizzo della successiva istruzione da prelevare.
* Lo stadio preliminary fetch usa l'indirizzo formato dallo stadio precedente e inizia a prelevare fino a 4 istruzioni per ciclo dalla cache di livello 1 delle istruzioni, inoltre in questa fase viene consultata la tabella dei salti per controllare se qualcuna di queste istruzioni è una diramazione condizionata.
* Lo stadio fetch completa il prelievo delle istruzioni dalla cache.
* Lo stadio brance target decodifica l'istruzioni prelevate.
* Lo stadio instruction group formation raggruppa le istruzioni in arrivo in base alle unità funzionali che devono utilizzare (ALU degli interi 1-2, ALU in virgola mobile e per le istruzioni grafiche 1-2, Pipeline delle diramazioni, operazioni di caricamento e di memorizzazioni).
* Lo stadio instruction grouping rimuove le istruzioni dalla coda e si prepara a inviarle al ciclo successivo alle unità di esecuzione. Esiste uno stadio che si occupa della ricerca dei registri richiesti dalle istruzioni su interi mentre per quello in virgola mobile inoltra la richiesta ai registri in virgola mobile.
* Lo stadio execution esegue le istruzioni su interi (istruzioni aritmetiche booleane di scorrimento) in un solo ciclo, al termine ogni istruzione aggiorna il banco dei registri di lavoro. Inoltre vengono prelevati dal banco dei registri in virgola mobile gli operandi in virgola mobile. Sempre all'interno di questo stadio vengono elaborate le istruzioni di salto condizionale e si determina l'eventuale diramazione da effettuare; se la predizione si rivela errata viene spedito un segnale allo stadio address generation e la pipeline viene svuotata.
* Nello stadio Cache vengono completati gli accessi alla cache L1. In questa fase le istruzioni che leggono la memoria ottengono i propri dati.
* Nello stadio Miss le parole di dati che sono state richieste, non presenti nella cache di livello 1, iniziano da essere elaborate. Viene effettuata una ricerca nella cache di livello 2 e se anche questa fallisce viene emesso un riferimento alla memoria che richiede un numero elevato di cicli.
* Nello stadio Write vengono scritti nel banco dei registri di lavoro i risultati.
* Nello stadio eXtend terminano gran parte delle operazioni grafiche e in virgola mobile e grazie allo store-to-load i risultati vengono resi disponibili alle prossime istruzioni prima che quest'utime siano state ritirate durante l'ultimo stadio.
* Le eccezioni e gli interrupt vengono rilevate dallo stadio Trap, salvando lo stato della macchina.
* L'ultimo stadio copia, nei rispettivi banchi di registri architetturali, i registri degli interi e dei numeri in virgola mobile.

## Livello ISA

A livello Isa tutte le macchine UltraSPARC sono identiche e la memoria indirizzabile è un vettore di 264 byte, anche se è così grande che i moderni calcolatori non la riescono ad implementare (attualmente c'è una limitazione sul numero d'indirizzi a cui si può accedere). Nel livello ISA dell'UltraSPARC l'organizzazione dei registri è molto complicata per cercare di ottimizzare le chiamate di procedura. L'UltraSPARC ha 2 tipi di registri: di uso generale e in virgola mobile.

* I registri di uso generale visibili al programma sono 32, anche se il loro numero è maggiore.
* I registri in virgola mobile sono 32 e possono contenere valori di 32 e 64 bit; questi ultimi si possono inoltre raggruppare per gestire valori di 128 bit.

In effetti, l'ISA dell'ultraSPARC utilizza una FINESTRA DI REGISTRI per migliorare la chiamata di procedura, cercando di emulare uno stack utilizzando però i registri, che risultano essere dunque divisi in vari gruppi da 32. Il registro CWP(current Window Pointer) tiene traccia dell'insieme dei registri utilizzati; sono di solito di 64 bit, il loro nome va da R0 a R31 e possono essere letti e scritti da molte istruzioni di caricamento (tranne R0 che contiene la costante 0). Altri registri vengono utilizzati per emulare lo stack. Tra questi SP (che indica l'attuale cima dello stack) e LV (che punta alla base dello stack). Se le finestre di registri disponibili si esauriscono a causa di procedure troppo annidate, l'insieme meno recente viene copiato in memoria per lasciar spazio a uno nuovo. Nell'ultraSPARC le sole operazioni che accedono alla memoria sono LOAD e STORE, tutti gli operandi sono contenuti nei registri (indirizzamento a registro) o nell'istruzione stessa (indirizzamento immediato) ma non in memoria, così come tutti i risultati devono essere salvati in un registro.

## Istruzioni

Le istruzioni ISA (32 bit) dell'UltraSPARC si trovano allineate in memoria, sono molto semplici e ognuna specifica una singola azione. Lo SPARC originale disponeva di pochi formati d'istruzione, ma col passare del tempo ne sono stati aggiunti di nuovi, che nella maggior parte dei casi derivavano dall'eliminazione di qualche bit in qualche campo. I primi due bit di ciascuna istruzione ne determinano il formato e indicano all'hardware dove trovare, se presente, il resto dell'opcode.

