# UltraSPARC IIi

L'UltraSPARC IIi, successeur de l'UltraSPARC, est un microprocesseur 64 bits de Sun Microsystems dont la distribution commença en 1997.
L'UltraSPARC IIi est basé sur les spécifications SPARC version 9, et équipe notamment les stations Sun allant de l'Ultra 5 à l'Ultra 60 ainsi que les premiers modèles de Sun Blade.

## Principaux blocs fonctionnels

Les principaux composants formant l'UltraSPARC IIi sont :
* IEU : Integer Execution Unit, effectue les opérations arithmétique grâce à ses 2 ALUs ;
* FPU : Floating Point Unit, effectue les opérations arithmétiques sur des nombres à virgule flottante ;
* GRU : GRaphic Unit, exécute les instructions graphiques (voir Jeu d'instructions) ;
* LSU : Load/Store Unit, accède à la mémoire ;
* PDU : Prefetch, Prediction and Dispatch Unit, contient la Prefetch queue et la logique pour le groupement des instructions ;
* I-Cache & D-Cache : caches de données et d'instructions ;
* I-MMU & D-MMU : Memory Management Unit, traduit les adresses virtuelles

## Registres

L'UltraSPARC IIi implémente la technique de la fenêtre de registres, c'est-à-dire qu'il met à disposition de l'utilisateur plusieurs jeux de registres interchangeables.
En plus des 8 registres globaux (%g0 à %g7), qui sont dupliqués selon le mode de fonctionnement du microprocesseur (4 modes sont disponibles), l'utilisateur a accès à une fenêtre coulissante de 24 registres :
* les registres d'entrée (%i0 à %i7), utilisés pour récupérer les arguments d'une fonction et lire la valeur de retour ;
* les registres locaux (%l0 à %l7), offrant un stockage pour les variables locales ;
* les registres de sortie (%o0 à %o7), permettant le passage d'argument à une fonction.
La fenêtre de registres est dite coulissante car dans le prologue d'une fonction, on fait appel à une instruction qui transforme les registres de sortie en registres d'entrée, et qui libère un nouveau jeu de 16 registres locaux et de sortie. Dans l'épilogue, on revient à l'ancienne fenêtre, ce qui a pour effet de restaurer les registres locaux et d'entrée.
L'UltraSPARC IIi offre 8 fenêtres de registres, au-delà, c'est au système d'exploitation d'assurer la sauvegarde des fenêtres précédentes contre l'écrasement. En effet, la fenêtre fonctionne de manière circulaire : une fois sur la dernière fenêtre, on reprend à la première.
La FPU offre 32 registres pouvant contenir soit des flottants simple précision soit des flottants double précision (IEEE 754).

## Pipeline

Le pipeline de l'UltraSPARC IIi est composé de 9 étages :
* fetch : lit un maximum de 4 instructions depuis le I-Cache ;
* decode : pré-décode et identifie les instructions ;
* group : choisit les instructions à exécuter (voir description ci-dessous) ;
* execute : exécute les instructions arithmétiques (à l'aide des 2 ALUs) ;
* cache : effectue la traduction d'adresse (voir Unité de gestion de la mémoire) ;
* N1 : résolution des caches-misses au niveau du D-Cache ;
* N2 : accès mémoire ;
* N3 : résolution des traps ;
* write-back : écriture des résultats finaux dans les registres.
L'UltraSPARC IIi est superscalaire de degré 4, c'est-à-dire qu'il peut exécuter selon certaines contraintes 4 instructions simultanément. Parmi ces contraintes :
* la présence de 2 ALUs permet l'exécution simultanée de deux instructions arithmétiques au maximum par groupe ;
* la FPU et la GRU permettent l'exécution d'un maximum de deux instructions simultanées, selon la nature des instructions dont il est question ;
* une instruction de branchement peut être exécutée, seulement si elle est la dernière du groupe d'instructions ;
* une instruction d'accès mémoire peut être exécutée par groupe.
Dans le cas des instructions FPU ou des instructions graphiques, la fin du pipeline diffère :
* register : accède aux registres flottants ;
* X1 : début de l'exécution des instructions ;
* X2 : continue l'exécution ;
* X3 : fin de l'exécution ;
* write-back : idem que dans le pipeline classique.
Chaque instruction de branchement est suivi d'un delay slot, c'est-à-dire une instruction qui sera systématiquement exécutée même si le branchement est pris. Il est possible d'annuler l'effet du delay slot, en utilisant des instructions particulières.

## Caches

* Le cache d'instructions (I-Cache) est un cache set associative de degré 2, contenant des blocs de 32 octets. Il y a 16 kilooctets au total.
* Le cache de données (D-Cache) est un cache direct mapped avec 2 sous blocs de 16 octets par ligne de cache. La politique de write-hit est de type write-through. Le D-Cache mesure 16 kilooctets, à l'instar de l'I-Cache.

## Jeu d'instructions

Le jeu d'instructions de l'UltraSPARC IIi est le Visual Instruction Set de Sun. Il offre :
* les instructions arithmétiques et logiques classiques ;
* les comparaisons et branchements ;
* les accès à la mémoire ;
* des instructions SIMD pour accélérer les traitements graphiques et sonores.

### Exemple en assembleur

La fonction suivante calcule la somme des entiers 64 bits d'un tableau.
On observe que l'addition juste après le branchement est exécutée même quand le branchement est pris. Mettre une instruction utile dans le delay slot permet ici de gagner un cycle par itération.

## Unité de gestion de la mémoire

La MMU de l'UltraSPARC IIi est formée par la LSU (Load/Store Unit) et les Translation Lookaside Buffers (TLB) : I-TLB et D-TLB.
La gestion de la mémoire virtuelle fait appel à deux TLB de 64 entrées de type full associative. Chaque entrée dans un TLB est divisée en 2 :
* le tag : contient l'adresse virtuelle, le flag Global et le numéro de contexte ;
* les données : précisent l'adresse physique, la taille de la page et les permissions.
Lorsqu'une adresse doit être traduite, les tags du TLB correspondant (I-TLB pour la lecture d'instructions, D-TLB pour les accès mémoire faits par la LSU), est parcouru à la recherche d'une adresse correspondante. Si une telle entrée est trouvée, le numéro de contexte est alors comparé au numéro de contexte courant, ou si la page est globale, alors cette comparaison n'est pas faite. Une fois l'entrée identifiée, la partie données est lue et l'adresse est traduite.
En cas de TLB-miss (c'est-à-dire si aucune entrée ne convient), le microprocesseur entame une recherche dans un cache placé en mémoire par l'utilisateur : le Translation Storage Buffer (TSB). Cette recherche est évidemment plus longue car il y a de nombreux accès mémoire. Cependant, l'utilisation du TSB est optionnelle.
Enfin, s'il n'existe aucune entrée ni dans le TLB ni dans le TSB, une exception est déclenchée. De la même manière, s'il existe une entrée mais que les permissions sont insuffisantes, une exception est aussi déclenchée. C'est alors au système d'exploitation :
* soit de remplir le TLB avec l'entrée manquante ;
* soit de changer les permissions pour autoriser l'opérations ;
* ou encore d'avertir l'utilisateur d'une erreur irrécupérable (Segmentation fault sous UNIX) et d'interrompre le programme.
Bien entendu, il faut très soigneusement maintenir les TLB, afin d'optimiser les performances et d'éviter les plantages.
Il est possible de contourner le mécanisme de traduction d'adresse, en utilisant 2 identifiants d'espace d'adressage spécifiques (Bypass ASIs). Cette opération est cependant réservée au superviseur.