Hiérarchie de la mémoire Les processeurs modernes requièrent beaucoup de mémoire rapide. Or, plus la mémoire est rapide, plus elle est chère. Que faire pour obtenir à coût raisonnable une machine performante? On utilise une hiérarchie de mémoires cache
Pourquoi les mémoires caches fonctionnent-elles? Les mémoires caches fonctionnent parce que les mêmes instructions sont réutilisées de multiples fois (évidemment si chaque instruction n’était utilisée qu’une seule fois, l’utilisation de la mémoire cache ne serait pas très en vogue…) On parle de localité des références: Localité temporelle Les instructions utilisées récemment sont souvent réutilisées Localité spatiale Les instructions voisines sont souvent exécutées de concert Localité séquentielle Les branchements constituent de 20 à 30% des instructions. Donc, de 70 à 80% des instructions s’exécutent toujours en séquence Les branchements vont souvent prendre les mêmes chemins pendant un certain temps (les branchements sont corrélés)
Pourquoi une hiérarchie de mémoire? Plus la mémoire a un temps d’accès petit, plus elle coûte cher. Il vaut donc la peine d’utiliser le moins possible de mémoire rapide tout en conservant une performance acceptable: Touchant le processeur, on a la mémoire la plus rapide (et aussi la plus chère) En bout de ligne, on a la mémoire principale, suivie du disque De nos jours, le premier niveau de mémoire cache se trouve souvent sur le même chip que le processseur (le 2e niveau peut aussi s’y retrouver)
Coût de la mémoire et temps d’accès
Taille de la mémoire cache et probabilité de « hit »
Mémoire cache: comment ça marche? L’idée de la mémoire cache, c’est de conserver dans une mémoire rapide les données dont on aura besoin bientôt Il existe plusieurs techniques pour distinguer les données emmagasinées dans la mémoire cache: Mapping associatif Mapping direct Mapping par ensemble associatif (set-associative)
Mémoire associative: comment ça marche Chaque entrée dans ce type de mémoire contient une clé et une valeur. Pour accéder à la valeur, il suffit de présenter la bonne clé (c’est la même idée que pour un tableau de hachage) Lorsqu’on présente une clé à ce type de mémoire, toutes les clés de toutes les entrées de la mémoire sont comparées en parallèle. Celle qui est identique (si elle existe) détermine quelle valeur est présentée à la sortie
Mémoire associative: comment ça marche 0x00000000 5823 0x00CCBB50 0xCC0011B0 2220 0xFFFFFFFF 155277 0x000011B0 0x00CCBB50 2220 0xCC0011B0 155277 0x000011B0 5823 Mémoire cache
Mémoire associative: pour ou contre? Avantages: Très flexible Peut être très rapide Inconvénients: Système coûteux (chaque élément de mémoire doit contenir un comparateur!)
Mapping direct … 0x000011B0 5823 Mémoire Comparateur Données 0x00CCBB50 Addresse (index) Étiquettes Taille de la mémoire: 64K X taille (données) Match?
Mapping direct: pour ou contre? Avantages: Utilise de la mémoire rapide mais « standard » (sans comparateur intégré) Moins coûteux que la mémoire associative Désavantages: Requiert un peu de circuiterie additionnelle Si 2 addresses utilisées dans la même période de temps ont le même index, il y aura continuellement des collisions…
Mapping set-associative 0x00CCBB50 Addresse (index) Étiquette Système à Mapping direct Système à Mapping direct Système à Mapping direct 1 32 1 32 1 32 Match? Données
Mapping set-associative: bilan Bon compromis entre mapping direct et mapping associatif: Moins coûteux que la mémoire associative Permet d’avoir des addresses dont les index sont les mêmes
Mémoire cache: que fait-on lorsque la mémoire est pleine? Lorsque la mémoire cache est remplie et une nouvelle valeur doit y être écrite, on doit faire de la place… Les méthodes utilisées sont variables: Remplacement aléatoire Remplacement « Least Frequently Used », LFU Un compteur comptabilise le nombre de fois qu’une valeur est utilisée Remplacement « Least Recently Used », LRU Avec une mémoire cache assez grande, les méthodes LRU et aléatoires donnent des résultats comparables (sachant que la méthode aléatoire est beaucoup plus simple à mettre en place, que choisiriez-vous?)
Mémoire cache: que fait-on lors d’écritures? Il existe deux méthodes de gérer les écritures en mémoire par le biais de la mémoire cache: Write-through: Dès qu’une nouvelle valeur est écrite, on fait l’écriture en mémoire principale, et on garde (ou pas) cette valeur dans la mémoire cache. Write-back: On conserve la nouvelle valeur dans la mémoire cache, et éventuellement on écrit cette valeur dans la mémoire principale Avantage du write-back: Une série de lectures/écritures à la même adresse n’implique pas de délai pour les écritures intermédiaires Avantages du write-through: lorsqu’on manque de place dans la mémoire cache (à cause d’un read miss), il n’y a jamais d’écriture requise
Mémoire cache: write-back, write-through Lorsque l’adresse de destination de l’écriture n’est pas en mémoire (write miss), on peut soit garder une copie dans la mémoire cache (write allocate), soit ne rien faire (no write allocate) Le write allocate est habituellement associé au write-back, où on espère qu’une prochaine écriture pourra se faire directement dans la mémoire cache Le no-write allocate est habituellement associé au write-through, puisque les écritures subséquentes vont de toutes façons aller jusqu’à la mémoire principale
La performance des mémoires cache La performance des mémoires cache dépend évidemment de la quantité de « misses ». On peut séparer ceux-ci en trois catégories: Obligatoires – lorsqu’on accède à une adresse pour la première fois De capacité – lorsque la mémoire cache était pleine et qu’on a dû laisser aller certaines des valeurs lues précédemment De conflit – lorsque deux adresses distinctes correspondent à la même entrée dans la mémoire cache La performance du système dépend aussi du délai encouru lors d’un « miss ». Pour optimiser la performance d’un système, il faut donc à la fois réduire le nombre de misses, et réduire les délais encourus lors de « misses »