« Fonctionnement d'un ordinateur/Les mémoires cache » : différence entre les versions

Contenu supprimé Contenu ajouté
Ligne 285 :
 
Au-dessus, on a vu des caches incapables de gérer plusieurs défauts simultanés.Voyons maintenant les caches capable de gérer un nombre limité de défauts de cache avant de bloquer, permettant ainsi aux lectures et écritures qui suivent un deuxième ou troisième défaut de fonctionner. Ceux-ci sont dits de type défaut après défaut (''miss under miss'').
 
====Les ''miss status handling registers''====
 
Pendant qu'un accès en RAM est démarré par le contrôleur mémoire, il ne peut pas démarrer de nouvelle lecture ou écriture en RAM immédiatement après (sauf dans certains cas exceptionnels). Il y a toujours un temps d'attente entre l'envoi de deux requêtes d'accès mémoire. Dans ces conditions, les autres défauts doivent être mis en attente tant que la RAM n'est pas libre pour démarrer une nouvelle requête. Cette mise en attente s’effectue des '''''miss status handling registers''''', que j’appellerais dorénavant MSHR. Ils sont aussi appelés des '''''miss buffer''''', ce nom trahisant le fait que la mise en attente réalisée par une petite mémoire plutôt que par des registres indépendants. Le nombre de MSHR donne le nombre de défauts simultanés maximal.
Ligne 295 ⟶ 297 :
Supposons qu'un défaut de cache aie lieu lors de la lecture ou écriture d'une adresse bien précise. Dans ce cas, le processeur va vérifier si un autre défaut de cache est en attente dans les MSHR, pour cette même adresse. Il réagira différemment suivant si c'est le cas ou non. Mais détecter cela demande de comparer l'adresse du défaut avec celles déjà mises en attente dans les MSHR. Pour ce faire, chaque MSHR est relié à un comparateur et avec quelques circuits, le tout formant une mémoire associative. On fait alors à deux situations, suivant qu'un défaut soit déjà en attente à la même adresse ou non. Si il n'y a aucun défaut de cache en attente à l'adresse à lire/écrire, il suffit de réserver un MSHR vide pour ce défaut. Dans le cas contraire, tout dépend du cache. Certains caches mettent le cache en pause, ce qui veut dire qu'il ne peut plus accepter de nouveau défaut de cache tant que le premier défaut de cache n'est pas résolu (le cache reste non-bloquant vu que le blocage a lieu pour des accès successifs à la même adresse seulement). D'autres caches sont plus malins, et peuvent mettre en attente plusieurs défauts de cache qui tombent sur la même adresse.
 
====Les accès simultanés à une même ligne de cache====
Les MSHR sont une première avancée, qui permet à un processeur de gérer plusieurs défauts de cache, associés à des lignes de cache différentes. Toutefois, un second accès mémoire à la même ligne de cache va bloquer le cache. On se retrouve alors dans deux cas. Dans le premier cas, les adresses des deux défauts de cache ont des tags différents et le premier défaut de cache doit finir avant que le second puisse démarrer. Dans l'autre cas, les tags sont identiques, mais pas les index et les décalages. Les données sont proches les unes des autres en mémoire et seront localisées dans la même ligne de cache. Quand le premier défaut de cache sera résolu, les données du second défaut de cache seront présentes dans le bloc. Dans ces conditions, il est inutile de bloquer le cache : le second défaut de cache peut être fusionné avec le premier.
 
Les MSHR sont une première avancée, qui permet à un processeur de gérer plusieurs défauts de cache, associés à des lignes de cache différentes. Toutefois, un second accès mémoire à la même ligne de cache va bloquer le cache. On se retrouve alors dans deux cas. Dans le premier cas, les adresses des deux défauts de cache ont des tags différents et le premier défaut de cache doit finir avant que le second puisse démarrer. Dans l'autre cas, les tags sont identiques, mais pas les index et les décalages. Les données sont alors proches les unes des autres en mémoire RAM et serontsont localisées dans la même ligne de cache, mais au même endroit. Quand le premier défaut de cache sera résolu, les données du second défaut de cache seront présentes dans le bloc. Dans ces conditions, il est inutile de bloquer le cache : le second défaut de cache peut être fusionné avec le premier.
 
Pour éviter de bloquer le cache dans la seconde situationcela, certains caches traitent les requêtes avec une granularité plus fine. Leur principe est simple : quand un défaut de cache a lieu et que celui-ci vaaccède lireà lesdes données chargées par un défaut de cache précédent, les deux défauts sont fusionnés dans le même MSHR. Cette détection de coïncidence de l'adresse s'effectue lors de la vérification des MSHR. : leLe tag contenu dans le MSHR est comparé avec le tag de l'adresse responsable du nouveau défaut de cache. Reste quequ'il lesfaut différents défauts de cache vont lire des données différentes dans le cache :mémoriser les index et les décalages despour adresseschaque sontdéfaut, différents.pour Lorsqueconfigurer le défautcache seracorrectement résolu,une et quefois la donnéeligne sera disponible, il faudra bien configurer lede cache avec les index et décalages correctsdisponible. Dans ces conditions, il faut bien les mémoriser quelque part., Etde préférence dans les MSHR sont tout indiqués pour cela.
 
La solution la plus simple consiste à utiliser des MSHR adressés implicitement. Ces MSHR contiennent une entrée pour chaque mot mémoire dans la ligne de cache concernée par le défaut. ChacuneChaque deentrée ces entrées diradit si un défaut de cache compte lire ou écrire dans le mot mémoire en question. Ces entrées contiennent diverses informations :
* la destination de la lecture effectuée par le défaut de cache (généralement un registre) ;
* un format, qui donne des informations sur l'instruction à l’origine du défaut ;
Ligne 305 ⟶ 309 :
* un bit empty, qui dit si l'entrée est vide ou non.
 
La fusion de deux défauts de cache est ainsi assez simple. Si deux défauts de cache vontà lirela même adresse lisent des mots mémoire différents, il suffirasuffit de configurer les entrées de mot mémoire de chaque défaut convenablement. Le premier défaut configurera ses entrées, et le second aura les siennes. Le même MSHR sera réutilisé pour les deux défauts. Et on peut ainsi gérer bien plus de deux défauts : tant que des défauts de cache vont lire des mots mémoire différents, on peut les fusionner, sans vraiment de limite. Par contre, si deux défauts de cache veulent réserver la même entrée, alors là, c'est le drame : le cache se bloque automatiquement ! Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant aux nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui ne se recouvrent pas peuvent avoir lieu en même temps.
 
Pour éviter de bloquer le cache lors d'accès à la même ligne de cache, certains chercheurs ont inventés des MSHR adressés explicitement. Ces MSHR sont aussi constitués d'entrées. La différence, c'est qu'une entrée est réservée à un accès mémoire, et non à un mot mémoire dans le cache. Chaque entrée va ainsi stocker :
Ligne 315 ⟶ 319 :
Avec cette organisation, le nombre de MSHR indique combien de lignes de cache peuvent être lues en même temps depuis la mémoire. Quant aux nombre d'entrées par MSHR, il détermine combien d'accès mémoires qui atterrissent dans la même ligne de cache peuvent avoir lieu en même temps, sans contraintes de recouvrement.
 
Généralement, plus on veut supporter de défauts de cache, plus le nombre de MSHR et d'entrées augmente. Mais au-delà d'un certain nombre d'entrées et de MSHR, les MSHR adressés implicitement et explicitement ont tendance à bouffer un peu trop de circuits. Utiliser une organisation un peu moins gourmande en circuits est donc une nécessité. Cette organisation plus économe se base sur des ''MSHR inversés''. Ces MSHR ne contiennent qu'une seule entrée, en quelque sorte : au lieu d’utiliser n MSHR de m entrée chacun, on va utiliser n × m MSHR inversés. La différence, c'est que plusieurs MSHR peuvent contenir un tag identique, contrairement aux MSHR adressés implicitement et explicitement. Lorsqu'un défaut de cache a lieu, chaque MSHR est vérifié. Si jamais aucun MSHR ne contient de tag identique à celui utilisé par le défaut, un MSHR vide est choisi pour stocker ce défaut, et une requête de lecture en mémoire est lancée. Dans le cas contraire, un MSHR est réservé au défaut de cache, mais la requête n'est pas lancée. Quand la donnée est disponible, les MSHR correspondant à la ligne qui vient d'être chargée vont être utilisés un par un pour résoudre les défauts de cache en attente.
 
Certains chercheurs ont remarqué que pendant qu'une ligne de cache est en train de subir un défaut de cache, celle-ci reste inutilisée, et son contenu est destiné à être perdu une fois le défaut de cache résolu. Ils se sont dit que, plutôt que d'utiliser des MSHR séparés, il vaudrait mieux utiliser la ligne de cache pour stocker les informations sur les défaut de cache en attente dans cette ligne de cache. Pour éviter tout problème, il faut rajouter un bit dans les bits de contrôle de la ligne de cache, qui sert à indiquer que la ligne de cache est occupée : un défaut de cache a eu lieu dans cette ligne, et elle stocke donc des informations pour résoudre les défaut de cache.