samedi 30 août 2008

Identity mapping, Demand paging et Copy on Write

Aller encore un petit tour avec des techniques qui utilise la mémoire virtuelle, aujourd'hui je vais vous présenter trois concepts vraiment très simple mais aussi très efficace.
Les deux derniers servent notamment à réduire la mémoire physique utilisé à un moment donnée ce qui n'est pas si mal puisque celle ci est beaucoup plus limité que la mémoire virtuelle.
Je ne vous l'avais peut être pas encore dit mais chaque processus à sa propre mémoire virtuelle d'ailleurs c'est pour ça qu'il ne peut pas accéder à la mémoire des autres processus or tout les processus partagent la même mémoire physique et la on voit bien que la mémoire physique est beaucoup plus utilisé que la mémoire virtuelle.


Bon alors commençons par l'identity mapping, concepts le plus simple qu'il existe, il s'agit d'un mapping à l'identique de la mémoire physique vers la mémoire virtuelle. Dans linux, l'identity mapping est utilisé pour l'espace noyau qui est le dernier giga de la mémoire virtuelle c'est à dire que 3G + x en mémoire virtuelle correspond à x en mémoire physique ceci facilite d'autant plus les manipulations de mémoire virtuelle. Cependant ont se heurte à un petit problème, comme l'espace noyau ne fait que 1G alors on ne pourra accèder qu'au premier giga de la ram. En fait ce qui ce passe dans linux c'est que les 128 derniers Mo sont réservés pour mapper le reste de la mémoire physique donc si le noyau à besoin d'un emplacement mémoire au dessus des 1G de la ram il va utilisait ces 128 derniers Mo pour mapper mais bon c'est top comme solution, il y a une autre solution c'est de donner 2G à l'espace noyau et 2G à l'espace user comme pour windows si je ne me trompe pas, bon le problème c'est qu'on diminue l'espace utilisateur et comme toute les librairies dynamiques sont mapper dans les 2G de l'espace utilisateur il vaut mieux ne pas en charger trop sinon il ne nous restera plus de mémoire mais bon il faut faire un choix soit on veut accéder à toute la mémoire physique soit on veut plus de mémoire virtuelle.


Bon maintenant passons à un premier concept qui va permettre d'économiser dans un premier temps la mémoire physique et donc on aura moins besoin de faire de manipulation de swap et les performances en seront améliorées.
Ce concept tout comme l'identity mapping est vraiment tout simple, en fait on va allouer l'espace mémoire que le programme à besoin en mémoire virtuelle mais pas en mémoire physique en fait il n'y aura pas d'association entre la mémoire virtuelle et la mémoire physique.
Voyons ça un peu plus en détail, la première chose que le programme va faire c'est qu'il va executer la première instruction de code ( logique non ? ) donc à ce moment là la première page virtuelle de code a été allouée ( ça a été fait par le loader quel qu'il soit -- elf, PE ... ) mais comme je l'ai dit aucune association avec la mémoire physique n'a été fait donc pagefault, a ce moment là l'OS va s'apercevoir qu'il n'y a pas d'association entre mémoire virtuelle et mémoire physique pour cette page donc normalement il devrait renvoyait un segfault ou accès violation sauf qu'il se rend compte que la mémoire physique a été alloué ( grâce à des structures internes ) et on arrive dans une situation de demand paging, il va alors copier les 4 premiers Ko de code grâce à fichier exécutable, les copier dans une page physique et faire une association entre mémoire physique et mémoire virtuelle pour cette page. Ensuite il réexecute la première instruction et là pas de problème puisqu'il y a association entre mémoire virtuelle et mémoire physique et ce jusqu'à ce qu'il sorte de cette page et rebellote copie du code dans une page physique et association entre mémoire virtuelle et mémoire physique sur la page en question, le même principe est appliqué pour les données.
Donc en fait on copie l'exécutable au fur et à mesure de son exécution et on retarde au plus possible les manipulations du swap.


Enfin voyons le Copy on Write souvent abrégé COW, qui est aussi une façon d'économiser l'utilisation de la mémoire physique.
Seulement ce concept ne s'applique seulement dans un cas précis celui du fork().
Bon déjà un fork c'est quoi ?
Un fork c'est tout simplement une duplication d'un processus, on dit que le créateur du second processus est le père et que le processus ainsi crée est le fils.
En fait ce qui se passe lors d'un fork c'est que le processus n'est pas dupliqué à partir de l'exécutable de base, sinon il y aurait deux fois le même code et bien entendu c'est absurde. Seul l'espace d'adressage ( la mémoire virtuelle avec ces associations avec la mémoire physique ) est dupliqué.
Seulement voila pour le code cela ne posera pas de problème puisque le code est en lecture seule seulement pour les données ça sera problématique puisque les deux processus n'auront pas forcément exactement les mêmes données au même moment, en général lors d'un fork on exécute un code différent pour le père et pour le fils mais même si le code exécuté était le même vu qu'on est dans un système multi-tâche, les deux processus s'exécute en même temps mais pas au même moment donc il y aura un conflit de données.
Il y a deux possibilités, soit la section ( une section est ensemble de pages ayant les même flags ) est en shared et dans ce cas là on laisse les deux processus partager cette section et après il se débrouille, soit la page est en private est la on utilisera le Copy on Write.
Le truc c'est que les sections private seront mis en lecture seule pour le fils donc lorsqu'il essayera d'écrire dans cette section ... pagefault, donc l'OS prend la main et se rend compte grâce à des structures internes que la page correspondante n'est pas réellement en lecture seule et qu'il s'agit d'un COW donc il va copier la page ( et non pas la section entière ) sur une nouvelle page physique changer l'association avec la mémoire virtuelle et relancer l'écriture.
Donc tant que le processus n'écrira pas sur une section private il n'y aura pas de nouvelle page physique d'allouer.


Voila pour ces trois concepts très intéressant que Linux implémente complètement ( je ne sais rien à propos de Windows si quelqu'un sait quelque chose merci de me le signaler ) et donc qui en améliore les performances et qui facilite la manipulation de l'espace kernel pour ce qui est de l'identity mapping.
Je pense qu'avec cet article j'ai fait le tour de ce que je pouvais dire sur la mémoire virtuelle en tout cas avec mes connaissances actuelles.
Dans tout les cas à bientôt dans un prochain épisode.

Aucun commentaire: