TP Architecture : Pipelines

Découverte et boucles

Travaillez dans le répertoire sim/pipe (au lieu du répertoire sim/seq auquel vous êtes habitué). Téléchargez le programme loop.ys dans ce répertoire ; le code est volontairement assez stupide.

Compilez le programme : make loop.yo et lancez le simulateur : ./psim -g loop.yo &

Les quatre barres bleues représentent des circuits combinatoires (fetch, decode, execute, memory) dont le détail est donné sur ces images. Chacun de ces étages est alimenté par un registre d'état (blanc) et alimente à son tour le registre d'état suivant ; par exemple l'étage Execute est un circuit combinatoire qui prend en entrée les signaux lus dans le registre d'état E (en blanc, situé en-dessous de la barre bleue) ; les sorties de cet étage sont affichées en gris au-dessus de la barre bleue et seront chargées dans le registre d'état blanc M au prochain signal d'horloge (d'où le terme Input affiché par le simulateur à côté de ces valeurs).

Sur les images détaillées des circuits et dans les fichiers hcl (Hardware Control Language) les champs d'un registre d'état sont préfixés par le nom du registre écrit en majuscule : cette convention permet par exemple de distinguer E_valA et M_valA. Les valeurs situées sur les lignes Input sont préfixées par le nom de l'étage qui les a calculées, écrit en minuscule : par exemple d_srcA est chargé dans E_srcA à chaque top d'horloge.

Appel de fonction, pile

Téléchargez le programme call.ys dans le répertoire pipe.

Dépendances de données

Téléchargez le programme fibo.ys dans le répertoire pipe ; ce programme calcule et écrit en mémoire les éléments de la suite de Fibonacci, on a juste remplacé les termes initiaux 1, 1 par 3, 5 pour qu'ils ne risquent pas d'être confondus. Ce programme n'est pas une fonction, il n'y a donc pas d'instruction call ou ret, ni d'instruction de manipulation de la pile push ou pop pour empiler ou dépiler les paramètres.

Appuyez trois fois sur Step, vous devez obtenir la situation suivante :

Cliché simulateur

Questions :

  1. Examinez la partie Decode Stage du fichier pipe-std.hcl et expliquez comment y a été calculée la valeur valB (new_E_valB dans le code HCL).

  2. Combien de cycles sont nécessaires pour que le registre edi soit mis à jour par la première instruction ?

  3. Faites la liste de toutes les dépendances de données dans ce programme, c'est-à-dire de tous les cas où une instruction a besoin de lire un registre dont la valeur n'est pas à jour (une instruction précédente est en train de la calculer). Dans chaque cas indiquez exactement comment le problème est résolu, c'est-à-dire comment est récupérée la valeur en cours de calcul. Vérifiez la solution en consultant le fichier pipe-std.hcl.

  4. Déplacez la cinquième instruction (initialisation du compteur) en tête du programme, recompilez et rechargez le simulateur. Examinez alors soigneusement la première exécution de la première instruction de la boucle et expliquez ce qui se passe ! Où ce cas est-il traité dans le fichier pipe-std.hcl ?

  5. Examinez (et expliquez) le traitement de l'instruction jne boucle lorsque le compteur %esi devient nul.

Mémoire et dépendances de données

Téléchargez le programme mem.ys dans le répertoire pipe.

Optimisation de programme

Téléchargez le programme cpi.ys dans le répertoire pipe.

Augmentez la vitesse d'exécution au maximum, laissez le programme tourner complètement. Observez la valeur CPI en bas à droite: c'est le nombre moyen de cycles par instruction, i.e. le nombre de cycles nécessaires pour exécuter le programme divisé par le nombre d'instructions exécutées. Il est supérieur à 1 à cause des bulles qui ont dû être insérées pour que l'exécution soit correcte.

Corrigez ce programme pour améliorer le nombre de cycles nécessaires pour exécuter le programme entier.