Mémoire virtuelle

Adresse logique vs adresse physique

On a vu dans la partie système d'exploitation que la mémoire vue par le process n'est pas celle qui est physiquement présente en RAM. Les adresses mémoires sont séparées en pages et les pages sont réordonnées pour chaque process. La mémoire vue par le process est appelée mémoire logique (ou virtuelle), la mémoire réelle est appelée mémoire physique.

Adresse et page

Chaque page contient une puissance de 2 adresses contiguës. Si la taille de la page est de 4KiB (valeur courante pour les x64),

On peut séparer une adresse en deux :

Remarquez que l'adresse à l'intérieur de la page est la même pour les adresses physiques et logiques.

Adressage valide

Actuellement, les processeurs x64 ont les spécificités suivantes pour l'adressage.

Ces limitations sont tout de même très larges :

A comparer avec les quantités de mémoire actuelles pour des ordinateur puissants :

Table de conversion

Pour chaque page virtuelle, il faut lui associer une adresse de page physique. Cette adresse prend $52-12 = 40b$.

On lui adjoint des informations utiles à l'OS comme :

Pour amener à une entrée sur 64b contenant :

Il est impossible de maintenir toute cette structure en mémoire car il faudrait $2^40 \cdot 8B = 8 TiB$ de stockage...

Structure

Comme un process ne va nécessite qu'u petit nombre de page, on utilise une structure arborée permettant, si nécessaire, de tout stocker mais également efficace pour en stocker une partie.

élément de design

Le stockage par une structure arborée permet :

  • de ne stocker que ce qui est nécessaire
  • d'être efficace vide (peut de nœud) et plein (on accède à chaque nœud en log du nombre de nœuds)

Cette structure possède un Overhead faible en temps (en log) et en place (ajout des nœuds en plus des données)

La structure est une structure arborée multi-level, elle comporte 4 niveaux en 64b :

Ce qui fait qu'une page sur 64 bit peut s'écrire en 4 nombres plus petit que 512 : ABCD

L'arbre est donc de racine une page de 512 entrée, initialement vide. Si u process contient la page d'adresse ABCD, on :

  1. vérifie si la racine possède un enfant à l'entrée A.
    1. si oui on y va
    2. si non on crée une page vide à l'entrée A de la racine et on y va
  2. vérifie si la page 2 possède un enfant à l'entrée B.
    1. si oui on y va
    2. si non on crée une page vide à l'entrée B de la page 2 et on y va
  3. vérifie si la page 3 possède un enfant à l'entrée C.
    1. si oui on y va
    2. si non on crée une page vide à l'entrée C de la page 3 et on y va
  4. vérifie si la page 4 possède un enfant à l'entrée D.
    1. si oui on trouve l'adresse physique
    2. si non lance une exception page fault pour que le noyau traite ce cas (soit en arrêtant le process soit en associant une page)

Seule les associations nécessaires sont stockées au prix d'un petit overhead :

Cette structure est stockée en mémoire et son emplacement est connue de la MMU.

Buffer dans la MMU

POur éviter les 4 appels à la mémoire au moindre chargement de page, la MMU possède un cache, la TLB qui possède habituellement 16 entrées, assez pour la plupart des process. Le sunny cove core possède ainsi deux TLB, un pour les instructions et un pour les données de 16 entrées chacune.

Et le cache dans tout ça ?

Le problème de cette transformation est que les caches L1 et L2 sont a priori placés avant la MMU et travaillent donc sur des adresses logiques. Ceci est fâcheux car :

C'est pourquoi les caches sont en fait stocké avec le tag de l'adresse physique. La taille de page fait que que tag sera identique pour l'adresse logique et physique.

On accélère le processus en faisant un appel à la page (le tag) en même temps que l'on cherche l'index dans le cache.