}}}
[[PageOutline]]
= 1 Objectifs =
L'objectif de ce TP est d'analyser en détail le modèle du composant '''!VciXcacheWrapper''', dont l'architecture interne a été présentée en cours. Ce composant contient quatre automates fonctionnant en parallèle (DCACHE_FSM, ICACHE_FSM, CMD_FSM et RSP_FSM), qui communiquent entre eux par des registres protégés par des bascules de type SET/RESET.
Il contient un tampon d'écriture postées, qui ne permet qu'une seule transaction d'écriture VCI à la fois.
Ce tampon est accédé par les trois automates DCACHE_FSM, CMD_FSM et RSP_FSM.
Après avoir analysé en détail le comportement du composant '''!VciXcacheWrapper''', on souhaite le modifier
pour qu'il utilise un tampon d'écritures postées plus évolué, supportant plusieurs transactions d'écriture simultanées,
et on évaluera expérimentalement le gain en performance obtenu.
= 2 Analyse du composant !VciXcacheWrapper =
Créez un répertoire de travail TP6, et décompressez l'archive [attachment:soclib_tp6.tgz soclib_tp6.tgz].
Cette archive contient en particulier les deux fichiers '''tp6_top.cpp''' et '''tp6_top.desc''', qui définissent une architecture monoprocesseur presque identique à celle du TP4. Elle contient une ROM, une RAM, un TIMER, un contrôleur TTY, un contrôleur de disque IOC, un contrôleur d'écran graphique FBF, un coprocesseur GCD, un contrôleur DMA et un concentrateur d'interruptions ICU.
La seule différence par rapport au TP4 est qu'on utilise un micro-réseau (composant '''!VciVgmn''') au lieu d'un bus (composant '''!VciVgsb'''). Le micro-réseau supporte plusieurs transactions simultanées, mais possède une latence importante: une vingtaine de cycles pour acheminer la commande VCI, et autant pour acheminer la réponse VCI.
L'application logicielle qui se trouve dans le répertoire '''soft''' est l'application d'affichage d'images sur le terminal graphique du TP4. Vous devez donc re-utiliser le fichier '''images.raw''' que vous avez utilisé dans le TP4.
Compilez l'application logicielle dans le répertoire '''soft''' . Générez le simulateur du prototype virtuel en utilisant le Makefile qui vous est fourni. Lancez l'éxécution de l'application logicielle sur le prototype virtuel:
{{{
$ ./simulator.x -IOCFILE path_to_images.raw
}}}
'''Question''' : En moyennant sur plusieurs images, évaluez le nombre de cycles nécessaires pour lire sur disque et afficher une image? Combien cela représente-t-il de cycles par pixel?
Vous pouvez consulter le code du composant !VciXcacheWrapper [http://www.soclib.fr/trac/dev/wiki/Component/VciXcacheWrapper ici], en cliquant sur les liens définis dans la section 2 (CABA implementation).
Ce composant utilise deux classes C++ pour représenter d'une part le tampon d'écritures postées
([http://www.soclib.fr/trac/dev/browser/trunk/soclib/soclib/lib/write_buffer/include write_buffer]),
et d'autre part les deux caches instructions et données
([http://www.soclib.fr/trac/dev/browser/trunk/soclib/soclib/lib/generic_cache/include generic_cache]).
Prenez le temps de lire le code du contrôleur de cache pour répondre aux questions suivantes:
'''Question''' : Comment est implémenté l'interface entre le contrôleur de cache et l'ISS (Instruction Set Simulator) représentant le processeur?
== __automate ICACHE__ ==
'''Question''' : Quels sont les conditions de sortie vers les deux états successeurs possibles de l'état IDLE de l'automate ICACHE_FSM ?
'''Question''' : Comment l'automate ICACHE transmet-il ses requêtes vers l'automate VCI_CMD?
'''Question''' : Si la réponse VCI à une lecture d'instruction signale une erreur d'adressage, comment cette erreur est-elle signalée au processeur?
'''Question''' : Donner l'expression de la condition ''irsp.valid'' (réponse valide à une requête de lecture instruction en provenance du processeur).
'''Question''' : représentez le graphe des transitions de l'automate ICACHE.
== __automate DCACHE__ ==
'''Question''' : Quelles sont les conditions de sortie vers les six états successeurs possibles de l'état IDLE de l'automate DCACHE_FSM ? Quelles sont les deux requêtes spéciales (autres que des lectures ou des écritures en mémoire) qui sont acceptées par ce composant ?
'''Question''' : Quelle est l'utilité de l'état DCACHE_MISS_SELECT?
'''Question''' : Si la réponse VCI à une lecture de donnée signale une erreur d'adressage, comment cette erreur est-elle signalée au processeur? Comment est signalée une erreur d'adressage suite une écriture ?
'''Question''' : Quels sont les états successeurs possibles de l'état DCACHE_WRITE_REQ?
'''Question''' : Donner l'expression de la condition ''drsp.valid'' (réponse valide à une requête de lecture ou d'écriture de donnée en provenance du processeu)?
'''Question''' : représentez le graphe des transitions de l'automate DCACHE.
== __automate VCI_CMD__ ==
'''Question''' : L'automate VCI_CMD peut être décrit comme un serveur. Quels sont ses clients? Quelle est la politique de priorité implémentée par ce contrôleur en cas de requête simultanée par différents clients?
'''Question''' : Quelles sont les 4 types de transactions VCI qui peuvent être émises par cet automate?
'''Question''' : Quelles sont les conditions de sortie vers les états successeurs de l'état IDLE?
'''Question''' : En consultant le code de l'objet write_buffer, expliquez le fonctionnement du tampon d'écritures postées. A quelle condition une transaction d'écriture VCI aura-t-elle une longueur supérieure à un flit?
'''Question''' : représentez le graphe des transitions de l'automate VCI_CMD.
== __automate VCI_RSP__ ==
'''Question''' : Quelles sont les conditions de sortie vers les états successeurs de l'état IDLE?
'''Question''' : Comment l'automate VCI_RSP communique-t-il avec les deux automates DCACHE et ICACHE?
Comment signale-t-il une éventuelle erreur de lecture reportée par la cible VCI?
'''Question''' : Comment l'automate VCI_RSP signale-t-il la fin d'une transaction d'écriture au tampon d'écritures? A quoi sert cette signalisation? Comment signale-t-il une erreur d'écriture reportée par la cible VCI?
'''Question''' : Représenter le graphe des transitions de l'automates VCI_RSP.
= 3 Instrumentation =
Le composant !VciXcacheWrapper contient un certains nombres de compteurs permettant d'afficher des statistiques sur le comportement du processeur et du cache. Bien qu'ils ne participent pas au fonctionnement du cache, ces compteurs se comportent comme des registres: ils sont donc initialisés lors du reset et sont incrémentés dans la fonction de transition. Du point de vue implémentation, ces registres d'instrumentations sont les variables membre de la classe !VciXcacheWrapper qui sont préfixées par '''m_'''.
Répondez précisément aux questions suivantes:
'''Question''' : Comment est calculé le nombre moyen de cycles par instruction (CPI) ?
'''Question''' : Comment sont calculés le ''miss_rate'' (taux de miss) et le ''miss_cost'' (coût moyen du miss) pour chacun des deux caches ?
'''Question''' : A quoi correspond le ''write_cost'' (cout moyen d'écriture) pour le tampon d'écritures postées ? comment est-il calculé?
Relancez la simulation en activant la génération des statistiques (avec une période de 100000 cycles) avec la commande suivante:
{{{
$ ./simulator.x -IOCFILE path_to_images.raw -STATS 1000000
}}}
'''Question''' : Qelles valeurs obtenez-vous à la fin de l'affichage de la première image, pour le CPI, les taux de MISS, le coût des miss, le coût des écritures ? Comment interprêtez-vous ces résultats ? Pour conforter votre interprétation, vous pouvez relancer la simulation en faisant varier la latence du NOC (paramètre -LATENCY sur la ligne de commande).
= 4 Modification du composant !VciXcacheWrapper =
Lorsque la latence des transactions est importante, le processeur est souvent gelé en raison de requêtes d'écriture qui ne peuvent être satisfaites car le tampon d'écritures est plein.
Plus ennuyeux, lorsque le tampon d'écriture est plein, le coût des miss augmente, car les écritures sont prioritaires par rapport aux lectures.
On souhaite donc modifier le contrôleur de cache pour qu'il utilise un tampon d'écritures plus évolué, permettant de ne pas attendre la réponse à une transaction d'écriture (n) pour envoyer la commande de la transaction (n+1). On souhaite également que les transactions de lecture - qui entraînent un gel du processeur - soient prioritaires par rapport aux transactions d'écriture, lorsque l'adresse de lecture ne correspond à aucune adresse d'écriture en attente dans le tampon d'écriture.
== 4.1 Tampon d'écritures postées ==
La classe C++ [http://www.soclib.fr/trac/dev/browser/trunk/soclib/soclib/lib/multi_write_buffer/include multi_write_buffer] modélise un tampon d'écritures postées plus évolué, permettant de stocker plusieurs requêtes d'écriture indépendantes. Chacune de ces requêtes peut avoir une longueur supérieure à un flit.
Analysez le code du multi_write_buffer pour répondre aux questions suivantes:
'''Question''' : Quelle est la signification des 4 arguments du constructeur de cet objet ?
'''Question''' : Quels sont les quatre états possibles d'une ligne du multi_write_buffer ?
'''Question''' : Qelles sont la ou les méthodes qui peuvent être utilisées par l'automate DCACHE_FSM pour modifier l'état interne du multi_write_buffer ?
'''Question''' : Qelles sont la ou les méthodes qui peuvent être utilisées par l'automate CMD_FSM pour modifier l'état interne du multi_write_buffer ?
'''Question''' : Quelles sont la ou les méthodes qui peuvent être utilisées par l'automate RSP_FSM pour modifier l'état interne du multi_write_buffer ?
'''Question''' : A quoi sert la méthode ''update()'' ? Pourquoi doit-elle être appelée à chaque cycle ?
== 4.2 Modification du contrôleur de cache ==
L'archive '''soclib_tp6.tgz''' qui vous est fournie contient un répertoire '''vci_xcache_wrapper_advanced''', qui contient lui_même les 3 fichiers '''vci_xcache_wrapper_advanced.cpp''', '''vci_xcache_wrapper_advanced.h''', '''vci_xcache_wrapper_advanced.sd''', décrivant une version modifiée du contrôleur de cache L1. Le fichier '''vci_xcache_wrapper_advanced.cpp''' est incomplet, et vous devez le compléter.
On rappelle que l'instruction assembleur ''sync'' a pour effet de synchroniser la mémoire, ce qui signifie en pratique que cette instruction est bloquante tant que toutes les instructions d'écriture précédant l'instruction ''sync'' n'ont pas été effectuées. Cette instruction se traduit par une écriture ''externe'' dans le pseudo-registre XTN_SYNC. Dans le composant '''vci_xcache_wrapper''', où les écritures sont prioritaires sur les lectures, l'instruction ''sync'' est simplement implémentée comme une instruction ''nop''. Cette implémentation n'est
plus possible dans un contrôleur de cache où les lectures peuvent passer avant les écritures.
Pour compléter le modèle du contrôleur de cache, vous respecterez les consignes suivantes:
* Le composant doit supporter plusieurs transactions VCI simultanées, avec la priorité suivante entre les 5 types de transactions : DMISS > IMISS > WRITE > DUNC > IUNC.
* Les requêtes DMISS et IMISS ne peuvent passer avant les requêtes de type WRITE enregistrées dans le tampon d'écritures que si elles portent sur des adresses différentes.
* Les requêtes d'écritures non cachables (correspondant généralement à une écriture dans un registre d'un périphérique) sont bloquantes, et ne sont donc pas enregistrées dans le tampon d'écritures postées.
* En cas d'instruction ''sync'' (écriture dans le pseudo registre XTN_SYNC), le processeur doit être bloqué tant que le tampon d'écritures postées n'est pas vide.
* Les deux automates VCI_CMD et VCI_RSP doivent être totalement synchronisées, et vous utiliserez le champs VCI TRDID pour identifier les différents types de transactions VCI s'exécutant en parallèle.
'''Question''' : Comparez les fichiers d'interface '''vci_xcache_wrapper.h''' et '''vci_xcache_wrapper_advanced.h''', et identifiez les modifications qui ont été introduites.
'''Question''' : Complêtez le fichier d'implémentation '''vci_xcache_wrapper_advanced.cpp'''
'''Question''' : Modifiez les fichier '''tp6_top.cpp''' et '''tp6_top.desc''' décrivant l'architecture globale, pour instancier
le composant !VciXcacheWrapperNew à la place du composant !VciXcacheWrapper, et renommez ces fichiers '''tp6_top_advanced.cpp''' et '''tp6_top_advanced.desc'''.
Générez le prototype virtuel pour l'architecture ainsi modifiée avec la commande ci-dessous. L'argument ( -I vci_xcache_wrapper_advanced ) indique à l'outil de compilation '''soclib-cc''' qu'il faut utiliser le répertoire local ''vci_xcache_wrapper_advanced''.
{{{
$ soclib-cc -P -p tp6_top_advanced.desc -o simulator_advanced.x -I vci_xcache_wrapper_advanced
}}}
Lancez l'exécution, en conservant une latence de 20 cycles pour le NOC (valeur par défaut), en définissant sur la ligne de commande les paramètres du tampon d'écritures (8 lignes de 4 mots), et en activant l'affichage des statistiques :
{{{
$ ./simulator_advanced.x -IOCFILE path_to_images.raw -WBUFW 4 -WBUFL 8 -STATS 1000000
}}}
'''Question''' : Combien faut_il de cycles pour charger et afficher une image en utilisant le composant '''multi_write_buffer'''? Comment varient les performances en fonction de la latence du NOC ?
'''Question''' : Est-il possible de diminuer la taille du tampon d'écriture postées sans dégrader trop fortement
les performances ?
= 5 Compte-Rendu =
Vous devez réaliser un compte-rendu pour ce TP en répondant aux questions et en décrivant le code que vous avez réalisé.