TD7 - UFMG

publicité
ASR1 – TD7 : Lara l’abeille
S. Collange, A. Panhaleux
ASR1 – TD7 : Lara l’abeille
{ Sylvain.Collange, Adrien.Panhaleux } @ens-lyon.fr
novembre 2010
Ce TD s’étale sur 3 séances. Lors des deux premières séances, chaque groupe crée un jeu
d’instruction pour un « CGPU ». À l’issu de ces deux séances, nous (les TD-men) choisirons
le meilleur des deux jeux d’instructions. Le processeur basé dessus sera construit dans la troisième séance, puis décrit en VHDL pour être enfin implémenté dans un FPGA dans les TD
suivants.
Présentation générale
Nous voulons construire un GPU moderne, c’est-à-dire un processeur parallèle qui est optimisé pour faire des dessins (calculer la couleur de plein de pixels). Dans la réalité, le GPU est
le plus souvent séparé du CPU. Ici, nous choisissons d’exécuter le code séquentiel (type CPU)
et le code parallèle (type GPU) sur le même processeur. Pour simplifier, on se limitera à du
rendu 2D.
Les programmes que notre CGPU exécutera seront semblables à ceci :
Tant que (joueur pas mort)
Mise à jour des position des objets et du joueur
Pour chaque pixel (i,j) dans [0,639]x[0,479] en parallèle
Image[i,j] = pixel calculé
Attendre synchronisation verticale
Pour chaque pixel (i,j) en parallèle
Image[i,j] = Dessin_GameOver[i,j]
Les boucles pour en parallèle correspondent à des sections de code qui sont exécutées en
mode parallèle. Nous interdisons au programmeur d’introduire des dépendances entre les
différentes itérations d’une boucle parallèle : leur ordre d’exécution n’est pas spécifié. Cette
restriction va bien nous simplifier le vie par la suite.
1. Avec du copier-coller, on peut construire un processeur multi-cœur et distribuer les itérations d’une boucle parallèle entre les cœurs. Quels sont les avantages et les inconvénients
de cette approche ? (penser au cas où le code parallèle est simple)
2. Avec un seul cœur muni d’instructions SIMD, comment peut-on faire ? Quelles sont les
difficultés ? (penser au cas où le code parallèle est complexe)
Les contraintes de notre processeur sont :
– être à peu près aussi efficace qu’un processeur SIMD sur du code parallèle régulier,
– permettre d’exécuter du code parallèle arbitrairement complexe (être aussi souple qu’un
multi-cœur),
1
ASR1 – TD7 : Lara l’abeille
S. Collange, A. Panhaleux
– pouvoir varier le nombre d’unités d’exécution à souhait sans toucher aux programmes
existants,
– partager le maximum de matériel (et d’effort de conception) entre l’exécution de la partie
séquentielle et de la partie parallèle.
Notre CGPU pourra fonctionner dans deux modes différents.
– Le processeur démarre en mode séquentiel. Ce mode offre toutes les fonctionnalités que
l’on est en droit d’attendre d’un CPU : calculs, lectures et écritures en mémoire à des
adresses arbitraires, structures de contrôle arbitraires, appels de fonctions. . .
Il doit également permettre de démarrer une section parallèle. On spécifie alors les bornes
de la boucle parallèle. On peut voir le corps de la boucle parallèle comme une fonction
séparée. Il faudra offrir au programmeur un moyen de passer des paramètres à ce corps
de boucle.
On prévoira aussi quelques moyens de discuter avec le contrôleur vidéo que vous faites
en DM : choix de la zone à afficher, signal de synchronisation verticale 1 .
– La partie parallèle doit être capable de lire n’importe où en mémoire (lecture de sprites,
textures. . .) On notera que si l’itération (i, j) lit ses données aux coordonnées (x+i, y +j),
c’est plus simple que si c’est à (ftordu (i, j), gbizarre (i, j)).
On doit pouvoir écrire le pixel résultant aux coordonnées (i, j) dans l’image finale. Cette
opération doit être efficace. Accessoirement, c’est pas plus mal si on peut écrire n’importeoù aussi.
On doit pouvoir effectuer des if-then-else, des boucles for et while, et indiquer la fin de
l’itération.
La première partie consiste à définir le jeu d’instructions, le format du mot d’instructions,
et à l’essayer sur quelques exemples. La seconde partie construit le processeur lui-même.
3. Quelles structures de données notre processeur va-t-il être amené à manipuler ? Quel
espace d’adressage et modes d’adressage le processeur va-t-il employer ?
4. Quelle est la taille mémoire qu’il peut adresser ?
5. Combien d’instructions aura-t-il au maximum ?
6. Dessinez la boîte noire de ce processeur, comportant tous les signaux d’interface avec la
mémoire et le contrôleur vidéo.
1
Le jeu d’instructions
On va découper le mot d’instruction en différents champs codant (entre autres) l’instruction
à effectuer, ses différents opérandes, etc.
Le principe d’orthogonalité de la philosophie RISC dit que ce découpage doit être constant,
même pour des instructions très différentes.
1. Discutez le principe d’orthogonalité. Qu’en est-il dans le cas de notre CGPU ?
1.1
Choix du nombre de registres
Il y a plusieurs grandes architectures possibles pour la partie calcul d’un processeur :
1. Ce qui nous permettra de faire du double-buffering entre autres choses rigolotes.
2
ASR1 – TD7 : Lara l’abeille
S. Collange, A. Panhaleux
– Machine à trois adresses : implémente des instructions de type Rd ← Rx op Ry, où Rd est
le registre destination, Rx et Ry sont les registres opérandes, et op est une opération arithmétique ou logique.
– Machine à deux adresses : le registre destination est obligatoirement un des registres opérandes, donc les instructions sont du type Rx ← Rx op Ry.
– Machine à une adresse, ou machine à accumulateur : toute opération met en jeu un registre
spécial, l’accumulateur (noté Acc), qui est à la fois destination et l’un des opérandes, soit
Acc ← Acc op Ry.
1. Donnez des exemples de processeurs (réels) qui sont des machines à trois, deux, une ou
quatre adresses.
2. Peut-on imaginer une machine à zéro adresse ?
3. Donnez le nombre de bits que va nécessiter le codage des opérandes et de la destination dans notre mot d’instruction, en fonction du choix d’architecture et du nombre de
registres du processeur.
4. Discutez et choisissez.
1.2
Registres
1. Quels sont les types de données dont nous avons besoin ?
2. Peut-on décomposer ces types en unités plus petites ? Peut-on rassembler ces types pour
former des unités plus grosses ?
3. Quelle sera une taille raisonnable pour nos registres ?
4. Peut-on accéder à un registre séquentiel en mode parallèle ? Peut-on accéder à un registre parallèle en mode séquentiel ? En lecture et/ou en écriture ? Si oui, quelle est la
sémantique associée ?
5. Les registres séquentiels forment-t-il un sous-ensemble des registres parallèles, ou sontils indépendants ?
6. Comment le processeur sait-il s’il doit considérer un registre séquentiel ou un registre
parallèle ? (dépend des réponses aux questions précédentes)
1.3
Instructions arithmétiques et logiques
Nous allons maintenant définir les quelques bits de notre mot d’instruction codant l’instruction (le champ instruction).
1. Quelles sont les opérations que nous avons besoin d’effectuer sur les types de données
choisis dans la section précédente ?
2. Définissez un jeu d’instructions minimal (ou en tout cas assez Reduced), qui permette
d’effectuer tout ça. Attention à la tentation d’intégrer toute l’algèbre linéaire et complexe
dans le jeu d’instruction.
3. Discutez les différentes possibilités pour faire des opérations par des constantes.
4. Récapitulez précisément le jeu d’instructions et discutez son codage le plus simple possible dans le champ instruction.
3
ASR1 – TD7 : Lara l’abeille
1.4
S. Collange, A. Panhaleux
Opérations mémoire
La philosophie RISC distingue bien les opérations de calcul, dont opérandes et destination
ne sont que des registres, et les opérations d’accès à la mémoire, qui n’effectuent aucun calcul.
1. Discutez les avantages et inconvénients de cette approche.
2. En mode parallèle, à quoi correspond une lecture/écriture ? Si vous avez autorisé le mélange de registres séquentiels et parallèles dans une même instruction, quelle est la sémantique associée ?
3. Comment réaliser les modes d’adressage que vous avez choisi au début ? Peut-on simplifier ou unifier en restant raisonnablement efficace ?
4. Y a-t-il des motifs d’accès particuliers qui offrent des possibilités d’optimisation ? Est-ce
que ça vaut la peine de compliquer le jeu d’instructions pour ça ? Discuter de ce qui peut
être fait en matériel par rapport à ce qui peut être fait par un compilateur.
5. Quelle est la largeur minimale d’une écriture en mémoire ? Peut-on émuler l’écriture de
mots plus petits en logiciel ?
6. Que faire en cas d’accès hors bornes ?
7. Que faire si on a plusieurs écritures concurrentes à la même adresse ?
1.5
Contrôle d’exécution
En cours, nous avons vu quelques techniques à base de prédication, piles, compteurs ou
PC multiples pour regrouper les instructions identiques.
1. Quelle solution choisir pour notre processeur ?
2. Quelles sont les conséquences sur le jeu d’instructions ?
3. Récapituler les différentes instructions de contrôle et leur sémantique.
4. Que fait-on lorsque le nombre d’itérations parallèles n’est pas un multiple du nombre
d’unités d’exécution ?
1.6
Récapitulation et bouche-trous
1. Récapitulez le mot d’instruction jusqu’ici. Reste-t-il des bits inutilisés et du temps libre ?
Si oui, voici des suggestions d’utilisation :
– Permettre des instructions SIMD en mode séquentiel.
– Donner des indications au matériel pour exécuter efficacement le code : durée de vie
des registres, structuration du contrôle. . .
– On peut faire jouer son imagination.
2. Complétez le jeu d’instruction, vérifiez qu’il n’y a pas (trop) de redondance dans les
instructions, récapitulez.
3. Votre CGPU connaît un grand succès. Vous êtes riches. Vous pouvez devenir encore plus
riches si vous construisez une version 2 avec plus de registres plus larges et plein de
nouvelles instructions. Mais il faut impérativement qu’elle reste compatible avec les programmes compilés pour la version 1. Comment faites-vous ? Peut-on faire mieux si on a
pensé à l’extensibilité dès le début ?
4
ASR1 – TD7 : Lara l’abeille
1.7
S. Collange, A. Panhaleux
Test : programmation en assembleur
1. Pour se convaincre de la qualité de notre jeu d’instruction, écrire quelques-uns des programmes suivants :
– dessin d’une nappe à carreaux (damier),
– produit de matrices,
– filtre basé sur une convolution genre détection des contours / flou gaussien,
– produit matrice creuse × vecteur (on choisira une représentation qui va bien pour la
matrice),
– affichage d’une image avec un effet de vague (ou drapeau qui flotte) 2 ,
– dessin d’une fractale de Mandelbrot (ou de Julia, au choix),
– lancer de rayon,
– Pong, Space Invaders,
– moteur de rendu 3D (rastérisation),
– Quake n,
– n’importe quel programme parallèle de votre choix.
2. Corrigez les réponses aux questions précédentes en fonction des oublis.
2. Par la transformation des coordonnées (x, y) → (x, y + β sin(αty)), où t varie avec le temps.
5
Téléchargement