Il existe différents types de mémoire selon leurs tailles et leurs temps d’accès :
Type de mémoire | Capacité | Temps d’accès |
---|---|---|
Processeurs et registres | Kilo-octet | 3/cycle |
Cache | Méga_octet | quelque cycles |
Mémoire RAM | Giga-octet | 200 cycles |
Mémoire virtuelle | Terra-octet | 10^6 cycles |
Les échanges entre les différents niveaux de mémoire se font par blocs.
L’un des premiers problèmes de la mémoire que c’est quelle s’améliore beaucoup moins vite que les processeurs. Ceci fait que les processeurs ne peuvent fonctionner avec la performance souhaiter car il est limité par les différents composants qui l’entoure (notamment la mémoire).
Plus les années passe et plus
Problème : Les accès mémoire sont de plus en plus couteux en terme de temps et de rapidité.
Pour pouvoir accélérer ces accès mémoire on utiliser la localité. Il y a deux types de localité : temporelle et spatiale.
La localité permet d’identifier de l’information utile et de la déplacer dans un cache ( mémoire très rapide). Ceci permet de gagner de temps lorsqu’il faudra réutiliser cette information.
Il existe deux types de mémoire : statique et dynamique.
La mémoire virtuelle est une mémoire crée par l’ordinateur afin de copier des variables utilent aux programmes. Cette mémoire vient au secours de la mémoire RAM lorsque celle-ci est remplise. Les variables sont alors copiés de la RAM vers votre disque dur et fait des aller-retours selon si la variable est beaucoup utilisé. Le défaut de cette technique c’est qu’une fois votre variable copié sur votre disque dur elle est accessible beaucoup moins rapidement sur dans la RAM et donc ralenti votre programme.
Dans les systèmes embarqués on n’utilise pas de mémoire virtuelle.
Dans la mémoire dynamique, les bits de poids fort de l’adresse sélectionne la ligne de la mémoire et les bits de poids faible de l’adresse sélectionne la colonne de la mémoire.
Voici comment lire une mémoire :
La lecture est destructive, c’est à dire qu’elle nécessite de réécrire les valeurs lues.
On va maintenant voir le nombre de cycle que prends l’utilisation d’une mémoire :
L’écriture dans une mémoire prends donc environ 40 cycles, ce qui est beaucoup. On essaie donc de limiter l’accès à la mémoire ou bien de mettre la donnée dans des caches si on veut y accéder rapidement.
Les mémoires dynamique fonctionnent avec accès en rafale (burst mode) : Lors de la lecture d’une donnée, on envoi les données environnantes dans la ligne, sans relecture de la ligne. L’ensemble est géré par un contrôleur mémoire qui est intégré au processeur.
On va maintenant voir le fonctionnement du processeur pentium :
NorthBridge : Assure les entreés/sorties rapides, notamment ceux de la mémoire et graphique.
SouthBridge : Assure les entrées/sorties plus lente. Comprend un contrôleur PCI et des contrôleurs de périphériques (SATA, USB, Ethernet).
La mémoire cache a été crée pour augmenter la rapidité de l’utilisation de la mémoire. La mémoire cache es plus petite que la mémoire RAM et se trouve au plus proche du processeur afin de limiter le temps de transition.
Voici comment marche un cache :
On cherche d’abord si la donnée est présente dans le cache
cache à correspondance directe (direct map) : ligne à un emplacement unique dépendant de son adresse.
Un des problèmes du cache à correspondance direct est qu’il ne faut pas de lignes différentes avec les même poids faibles d’adresse.
Cache associatif : ligne à un emplacement quelconque. Ceci évite que des lignes avec les mêmes poids faibles d’adresse ne s’écrasent mutuellement, mais nécessite une recherche complexe.
Cache associatif par ensemble (set associative) : ligne à un emplacement quelconque dans un bloc déterminé par l’adresse. Bon compromis car l’ensemble fait quelques lignes.
Déplacement : adresse de l’octet dans la ligne
Index : La position de la ligne dans le cache
Etiquette : les poids forts identifient la ligne de cache
Si on insère une nouvelle ligne dans le cache, il faut en supprimer une.
Pour cela il y a on va voir différentes manières de faire :
— On supprime la moins fréquemment utilisée (least frequentlu used LFU)
— On supprime la moins récemment utilisée (least recently used LRU)
Pour cela on va voir le pseudo LRU :
1bit-PLRU : A chaque accès, on indique avec un bit si la ligne est dans la partie haute ou basse de l’ensemble. En cas d’échec, prendre une ligne aléatoire de l’autre partie
bit-pLRU : On associe à chaque ligne un bit d’état. A chaque accès à la ligne, le bit est mis à 1.
En cas d’échec on remplace une des lignes dont le bit d’état est à 0.
— S’il en a plusieurs, on en choisit une (aléatoirement, celle avec le plus petit index, …) et on met son bit d’état à 1.
— S’il n’y a qu’une ligne dont le bit d’état est à 0, on la choisit et on complémente tous les bits d’état
Cache à écriture simultanée (write-through) : On écrit simultanément dans le cache et la mémoire pour assurer la cohérence des information. Le problème du cache à écriture simultané est l’encombrement du bus.
Cache à réécriture (write-back) : Lors d’une écriture en cache, on marque la ligne comme modifiée. La deuxième étape et de réécrire la ligne en mémoire. On réécrit seulement si la ligne est supprimée du cache ou si elle a été modifiée. Le cache à réécriture est plus complexe, mais charge moins le bus.
Write allocate : Lors d’une écriture, on crée une entrée pour la ligne dans le cache. Nécessite une lecture de la ligne, mais plus efficace en cas d’écritures successives dans la même ligne.
No-write allocate : La donnée est directement envoyée à la mémoire. On n’alloue une ligne que sur une lecture.
Caches séparés (split caches) : Un cache pour les instructions et un pour les données. Permet d’éviter les conflits d’accès à la mémoire dans le processeur
Cache unifié (unified cache) : Un cache unique stockant instructions et données. Permet une meilleure utilisation de la capacité du cache.
Il y a trois choses que l’on souhaite réduire : le taux d’échec, le temps d’accès et d’échec.
Obligatoire : Le premier échec arrive lors de la première utilisation du cache qui ne contient aucune donnée et donc donne un échec
Capacité : taux d’échec du à une capacité trop faible et donc plus de place pour ajouter de nouvelle donnée
Conflits : Taux d’échec du à des conflits (cela n’arrive pas avec un cache totalement associatif)
Ni la capacité, ni l’associativité n’influent sur les échecs obligatoires. La capacité réduit les échecs de conflits et de capacité. L’associativé n’influence que les échecs dus à des conflits.
On peut réduire le taux d’échec en augmentant la taille des lignes ou bien en anticipant la demande des données (prefetch)
Impact de la taille des lignes
La taille des lignes est très importante dans votre cache :
Un bon compromis est entre 32/64 octets.
Réduction des échecs dus à des conflits permet d’augmenter l’associativité grâce au cache de victime.
Cache des victimes : Quand une ligne est éjectée, on la met dans un petit cache totalement associatif. Si on a a nouveau besoin de cette ligne, elle sera directement
disponible.
On utilise plusieurs niveaux de caches successifs pour permettre d’augmenter le temps d’accès à la donnée.
Cache de niveau 1 : C’est le cache le plus proche du processeur. Il doit fournir des données quitte à avoir un taux d’échec un peu élevé.
Caches de niveau L2 et L3 : Plus loin du processeur, on doit donc limiter les accès mémoire pour réduire le coût d’un échec. Il sont de plus grande taille et plus sophistiqués, mais leur temps d’accès est plus important.
Cache L1 | Cache L2 | Cache L3 | |
---|---|---|---|
Objectif | Cache rapide pour alimenter le processeur | Réduire le temps d’échec du cache L1 et limiter au maximum les accès à la mémoire | Réduire le temps d’échec du cache L1 et limiter au maximum les accès à la mé- moire |
Type de cache | Deux caches séparés données et instructions | Cache unifié instructions/données | Cache unifié instructions/données |
Temps d’accès | 1–5 cycles | 3–20 cycles | 10–40 cycles |
Temps d’échec | 3-15 cycles | 10-40 cycles | 200 cycles |
Taille associativité | 2×16–32 ko Faible associativité | 256 ko Associativité plus importante | 1Mo+ Associativité plus importante |
Ecriture | Écriture simultanée (pour simplifier le cache) ou réécriture | Réécriture (pour limiter le trafic mémoire et la consommation) | Réécriture (pour limiter le trafic mémoire et la consommation) |
Les caches L1 et L2 des différents processeurs communiquent pour assurer la cohérence mémoire.
Les caches successifs peuvent être inclusifs ou exclusifs
Caches strictement inclusifs : L1 ⊂ L2 ⊂ MP
Tout ce qui est dans L1 est aussi dans L2.
Simplifie la mise en œuvre
Caches non strictement inclusifs : L1 ∩ L2 6 = ∅
L1 peut contenir une partie de L2 et réciproquement. Une ligne n’est jamais à la fois dans L1 et L2. Évite de dupliquer l’information.
Si on cherche une information dans L1 et qu’on ne la trouve pas alors on l’a copie depuis la mémoire principale.
Si on ne trouve pas une donnée dans L1 mais qu’elle se trouve dans L2 alors la donné est copié de L2 vers L1.
Il est nécessaire de prendre en compte les caches dans les évaluations de performances.
Nous supposons des caches avec un temps d’accès ta , un taux d’échec τe .
Le temps d’accès à la mémoire est tM