= Questions - Réponses pour la préparation de la session 2 de l'année 2019-2020 == A propos du format du sujet * **Où et quand ?**[[BR]] L'examen se déroulera dans l'**amphi 34B** sur le campus Pierre et Marie Curie le **mercredi 1er juillet 2020**. * **Est-ce que c'est un sujet "standard" ?**[[BR]] Hormis le fait qu'il n'y a que 3 parties, ce sera un sujet standard. Vous pouvez vous référer aux annales corrigées. * Assembleur * Cache * GIET et un peu d'archi (probablement un QCM) * **Documents**[[BR]] Seuls les fascicules sur le GIET et le MIPS (architecture et assembleur) sont autorisés. == Programmation assembleur * **Qui fait le prologue et l’épilogue la fonction appelante ou la fonction appelée ?**[[BR]][[BR]] >C'est la fonction appelée qui a un prologue et un épilogue. [[BR]] >Lorsque fonction `f()` appelle une fonction `g()`, elle se contente de placer les arguments dans les registres `$4` à `$7`et de faire un saut à `g()` par >l'instruction `jal g`. > >**Prologue**[[BR]] >Lorsqu'on commence à exécuter `g`, il faut exécuter un prologue dont voici les étapes : >1. créer le contexte d'exécution dans la pile pour `g()` avec l'instruction `addiu $29, $29, -X` où `X` est le nombre d'octets pris dans la pile (c'est > >toujours un multiple de 4). Ces `X` octets vont servir à trois choses : > 1. sauver la valeur des registres persistants que `g()` va utiliser dont `$31`. > 2. réserver de la place pour les variables locales de la fonction `g()` > 3. réserver de la place pour les arguments des fonctions que `g()` va appeler. >2. Sauver les registres persistants que `g()` va utiliser dans la place réservée pour eux à l'étape précédente [[BR]] > C'est donc une suite de `sw $x, d($29)` où `d` est toujours positif et multiple de 4. >3. Sauver les arguments reçus par `g()` (dans `$4` à `$7`) à la place réservée par `f()` (c'est-à-dire dans le > contexte de `f()`). [[BR]]Cette étape n'est pas toujours présente, elle n'est utile que si `g()` appelle elle-même. > des fonctions et qu'elle a donc besoin de changer la valeur des registres `$4` à `$7` alors qu'elle en a besoin après > ses fonctions appelées. > >**Epilogue**[[BR]] >Avant de sortir de `g` on doit exécuter l'épilogue qui consiste à : >1. restaurer l'état des registres persistants sauvés lors du prologue avec une séquence de `lw $x, d($29)` >2. restaurer l'état du pointeur de pile `addiu $29, $29, X` * **Quand on est en mode user peut on masquer les interruptions ?**[[BR]][[BR]] >Non, c'est impossible parce que pour masquer les interruptions, il faut : >* soit écrire dans le registre status en utilisant l'instruction mtc0.[[BR]]Or cette instruction est interdite en mode user, l'utiliser provoque une exception. >* soit écrire dans le registre de masque de l'ICU dont l'adresse est "mappée" (placée) au-delà de 0x80000000.[[BR]] Or y écrire est interdit en mode user, cela provoque une exception. == Rappel de cours sur les caches Je vous recommande de revoir les transparents des 2 cours sur les caches ([htdocs:cours/ALMO-2019-5_Cache.pdf Hiérarchie mémoire et techniques de cache] et [htdocs:cours/ALMO-2019-6_Cache-suite.pdf Caches (suite)]). 1. Ligne de cache et case de cache.\\ Je vais faire l'hypothèse que vous avez compris ce qu'est une ligne de cache et une case de cache.\\ Le cache lit des lignes en mémoire et il les copie dans ces cases.\\ 2. Numéro de ligne\\ Les lignes sont des segments d'adresse de 8 ou 16 ou 32 ou 64 octets alignés en mémoire (l'adresse du premier octet est un multiple de sa taille).\\ Les lignes sont numérotées et pour connaitre dans quelle numéro de ligne se trouve un octet quelconque, il suffit de diviser l'adresse de l'octet par la taille d'une ligne. 3. Case de cache. Quand le cache lit une ligne en mémoire, il doit la placer dans l'une de ces cases.\\ Le numéro de la case utilisé pour ranger une ligne se nomme index de ligne.\\ Comme le nombre de cases est une puissance de 2, le nombre de bit de l'index est juste le log2 du nombre de cases.\\ Par exemple, pour 16 cass il faut 4bits pour l'index, pour 128 cases il faut 7 bits, pour 256 cases il faut 8 bits.\\ 4. Correspondance directe Dans un cache à correspondance directe, la case choisie pour une ligne ne dépend que de son numéro (de ligne).\\ Plus précisement, on utilise comme index les bits de poids faible du numéro de ligne.\\ Quand on pose la question suivante : quels éléments d'un tableau sera rangé dans une case d'index C du cache ? * Il faut commencer par regarder quelles lignes en mémoire utilisent le tableau. C'est possible de savoir ça, parce qu'on connait l'adresse du tableau en mémoire et la taille des lignes. * Puis quand on connait les lignes, il faut regarder dans quelles cases du cache, elles sont rangées. * Puis enfin, vous pouvez en déduire ce qu'il y a dans une case en particulier. Attention si le tableau est plus grand que le cache, alors une case du cache, est utilisé pour plusieurs éléments du tableau. {{{ #!comment * Le processeur dispose d'un espace d'adressage 32bits. Cela veut dire qu'il peut donc former des adresses de 32bits et accéder à 2^32^ octets. * Quand le processeur accède à la mémoire, il lit ou il écrit le plus souvent des mots de 4 octets. \\ Un mot peut être vu comme un segment d'adresse de 4 octets.\\ Les mots sont alignés, ce qui signifie que l'adresse du premier octet est un multiple de sa taille, donc multiple de 4. * Les caches de niveau 1 (L1) sont placés entre le processeur et la mémoire. \\ Il y a un cache pour les instructions et un cache pour les données. * Les caches permettent de réduire le nombre d'accès à la mémoire en faisant une copie locale des instructions ou des données lues.\\ L'efficacité des caches repose sur deux propriétés des programmes : la localité spatiale et temporelle des accès à la mémoire. * La localité temporelle, c'est le fait que si un programme accède à une donnée (ou à une instruction),\\ il y a une forte probabilité qu'il y accède à nouveau dans peu de temps. * La localité spatiale, c'est le fait que si un programme accède à une donnée (ou à une instruction),\\ il y a une forte probabilité qu'il accèdes aux adresses voisine.|i * Pour profiter de ces propriétés, quand le processeur demande une donnée, il la demande au cache et si c'est la première fois\\ le cache va lire la donnée demandée et les données voisines (localité spatiale)\\ et les copier localement pour éviter de nouveaux accès à la mémoire lors ques prochain accès (localité temporelle). * Le cache lit des petits segments d'adresses que l'on nomme des lignes de cache.\\ Une ligne de cache a une taille puissance de deux octets et forcément plus grande qu'un mot, donc 8, 16, 32, voire 64 octets (rarement plus).\\ Les lignes sont alignées (adresse du premier octet est multiple de sa taille). * Le cache stocke les lignes de cache dans des cases de caches. * Donc, quand le processeur fait une lecture de donnée le cache détermine le numéro de la ligne dans laquelle se trouve cette données }}}