Fichier mappé en mémoire - Memory-mapped file

Un fichier mappé en mémoire est un segment de mémoire virtuelle qui a reçu une corrélation directe octet pour octet avec une partie d'un fichier ou d'une ressource de type fichier. Cette ressource est généralement un fichier physiquement présent sur le disque, mais peut également être un périphérique, un objet de mémoire partagée ou une autre ressource que le système d'exploitation peut référencer via un descripteur de fichier . Une fois présente, cette corrélation entre le fichier et l'espace mémoire permet aux applications de traiter la partie mappée comme s'il s'agissait de mémoire principale.

Histoire

TOPS-20 PMAP

Un début ( c.  1969 ) la mise en œuvre de ce fut le PPAFM appel système sur le DEC-20 « s TOPS-20 système d'exploitation, une fonction utilisée par de Software House système de base de données système-1022 .

SunOS 4 mmap

SunOS 4 introduit Unix de mmap , ce qui a permis des programmes « pour cartographier les fichiers dans la mémoire. »

Fichiers mappés en mémoire extensibles Windows (GMMF)

Deux décennies après la sortie du PMAP de TOPS-20, Windows NT a reçu des fichiers GMMF (Growable Memory-Mapped Files).

Puisque «la CreateFileMapping fonction nécessite qu'une taille lui soit transmise» et que la modification de la taille d'un fichier n'est pas facilement acceptée, une API GMMF a été développée. L'utilisation de GMMF nécessite de déclarer le maximum auquel la taille du fichier peut augmenter, mais aucun espace inutilisé n'est gaspillé.

Avantages

L'avantage du mappage de mémoire d'un fichier augmente les performances d'E / S, en particulier lorsqu'il est utilisé sur des fichiers volumineux. Pour les petits fichiers, les fichiers mappés en mémoire peuvent entraîner une perte d' espace libre car les mappages de mémoire sont toujours alignés sur la taille de la page, qui est principalement de 4 Kio. Par conséquent, un fichier de 5 Kio allouera 8 Kio et donc 3 Kio sont gaspillés. L'accès aux fichiers mappés en mémoire est plus rapide que l'utilisation d'opérations de lecture et d'écriture directes pour deux raisons. Premièrement, un appel système est d'un ordre de grandeur plus lent qu'une simple modification de la mémoire locale d'un programme. Deuxièmement, dans la plupart des systèmes d'exploitation, la région de mémoire mappée est en fait le cache de pages du noyau ( cache de fichiers), ce qui signifie qu'aucune copie ne doit être créée dans l'espace utilisateur.

Certaines opérations sur les fichiers mappés en mémoire au niveau de l'application fonctionnent également mieux que leurs homologues de fichiers physiques. Les applications peuvent accéder et mettre à jour les données du fichier directement et sur place, au lieu de rechercher depuis le début du fichier ou de réécrire l'intégralité du contenu édité dans un emplacement temporaire. Étant donné que le fichier mappé en mémoire est géré en interne dans les pages, l'accès aux fichiers linéaires (comme on le voit, par exemple, dans le stockage de données de fichier plat ou les fichiers de configuration) nécessite un accès au disque uniquement lorsqu'une nouvelle limite de page est franchie et peut écrire des sections plus grandes fichier sur disque en une seule opération.

Un avantage possible des fichiers mappés en mémoire est un "chargement paresseux", utilisant ainsi de petites quantités de RAM même pour un très gros fichier. Essayer de charger le contenu d'un fichier qui est beaucoup plus grande que la quantité de mémoire disponible peut causer de graves raclée que le système d'exploitation lit à partir du disque en mémoire et écrit simultanément les pages de la mémoire sur le disque. Le mappage de mémoire peut non seulement contourner complètement le fichier d'échange, mais également permettre le chargement de sections de plus petite taille au fur et à mesure que les données sont modifiées, de la même manière que la pagination à la demande utilisée pour les programmes.

Le processus de mappage de mémoire est géré par le gestionnaire de mémoire virtuelle , qui est le même sous-système chargé de traiter le fichier d'échange . Les fichiers mappés en mémoire sont chargés en mémoire une page entière à la fois. La taille de la page est sélectionnée par le système d'exploitation pour des performances maximales. La gestion des fichiers d'échange étant l'un des éléments les plus critiques d'un système de mémoire virtuelle, le chargement de sections de la taille d'une page d'un fichier dans la mémoire physique est généralement une fonction système très optimisée.

Les types

Il existe deux types de fichiers mappés en mémoire:

Persisté

Les fichiers persistants sont associés à un fichier source sur un disque. Les données sont enregistrées dans le fichier source sur le disque une fois le dernier processus terminé. Ces fichiers mappés en mémoire conviennent pour travailler avec des fichiers source extrêmement volumineux.

Non persistant

Les fichiers non persistants ne sont pas associés à un fichier sur un disque. Lorsque le dernier processus a fini de travailler avec le fichier, les données sont perdues. Ces fichiers conviennent à la création de mémoire partagée pour les communications inter-processus (IPC).

Désavantages

La principale raison de choisir les E / S de fichier mappées en mémoire est la performance. Néanmoins, il peut y avoir des compromis. L'approche d'E / S standard est coûteuse en raison de la surcharge des appels système et de la copie de la mémoire. L'approche mappée en mémoire a son coût en erreurs de page mineures - lorsqu'un bloc de données est chargé dans le cache de page , mais n'est pas encore mappé dans l'espace de mémoire virtuelle du processus. Dans certaines circonstances, les E / S de fichier mappées en mémoire peuvent être considérablement plus lentes que les E / S de fichier standard.

Un autre inconvénient des fichiers mappés en mémoire concerne l' espace d'adressage d'une architecture donnée : un fichier plus grand que l'espace adressable ne peut avoir que des portions mappées à la fois, ce qui complique sa lecture. Par exemple, une architecture 32 bits telle que l' IA-32 d' Intel ne peut adresser directement que 4 Gio ou des portions plus petites de fichiers. Une quantité encore plus petite d'espace adressable est disponible pour les programmes individuels, généralement de l'ordre de 2 à 3 Gio, selon le noyau du système d'exploitation. Cet inconvénient est cependant pratiquement éliminé sur l' architecture 64 bits moderne .

mmap a également tendance à être moins évolutif que les moyens standard d'E / S de fichiers, car de nombreux systèmes d'exploitation, y compris Linux, ont un plafond sur le nombre de cœurs gérant les erreurs de page. Les appareils extrêmement rapides, tels que les SSD NVM Express modernes , sont capables de faire de la surcharge une réelle préoccupation.

Les erreurs d'E / S sur le fichier sous-jacent (par exemple, son lecteur amovible est débranché ou le support optique est éjecté, le disque est plein lors de l'écriture, etc.) lors de l'accès à sa mémoire mappée sont signalés à l'application sous forme de signaux SIGSEGV / SIGBUS sur POSIX, et le Exception structurée EXECUTE_IN_PAGE_ERROR sous Windows. Tout code accédant à la mémoire mappée doit être prêt à gérer ces erreurs, qui ne se produisent normalement pas lors de l'accès à la mémoire.

Seules les architectures matérielles avec une MMU peuvent prendre en charge les fichiers mappés en mémoire. Sur les architectures sans MMU, le système d'exploitation peut copier le fichier entier en mémoire lorsque la demande de mappage est faite, mais cela est extrêmement coûteux et lent si seulement une petite partie du fichier est accessible, et ne peut fonctionner que pour les fichiers qui rentrera dans la mémoire disponible.

Utilisations courantes

L'utilisation la plus courante d'un fichier mappé en mémoire est peut-être le chargeur de processus dans la plupart des systèmes d'exploitation modernes (y compris Microsoft Windows et les systèmes de type Unix.) Lorsqu'un processus est démarré, le système d'exploitation utilise un fichier mappé en mémoire pour amener le fichier exécutable , ainsi que tous les modules chargeables, en mémoire pour exécution. La plupart des systèmes de mappage de mémoire utilisent une technique appelée pagination à la demande , où le fichier est chargé dans la mémoire physique en sous-ensembles (une page chacun), et uniquement lorsque cette page est effectivement référencée. Dans le cas spécifique des fichiers exécutables, cela permet au système d'exploitation de charger de manière sélective uniquement les parties d'une image de processus qui doivent réellement s'exécuter.

Une autre utilisation courante des fichiers mappés en mémoire consiste à partager la mémoire entre plusieurs processus. Dans les systèmes d'exploitation modernes en mode protégé , les processus ne sont généralement pas autorisés à accéder à l'espace mémoire alloué à un autre processus. (La tentative d'un programme de le faire entraîne des erreurs de page non valides ou des violations de segmentation .) Il existe un certain nombre de techniques disponibles pour partager la mémoire en toute sécurité, et les E / S de fichiers mappés en mémoire sont l'une des plus courantes. Deux applications ou plus peuvent mapper simultanément un seul fichier physique en mémoire et accéder à cette mémoire. Par exemple, le système d'exploitation Microsoft Windows fournit un mécanisme permettant aux applications de mapper en mémoire un segment partagé du fichier d'échange du système lui-même et de partager des données via cette section.

Prise en charge de la plate-forme

La plupart des systèmes d'exploitation ou des environnements d'exécution modernes prennent en charge une forme d'accès aux fichiers mappés en mémoire. La fonction mmap () , qui crée un mappage d'un fichier à partir d'un descripteur de fichier, d'un emplacement de départ dans le fichier et d'une longueur, fait partie de la spécification POSIX , donc la grande variété de systèmes compatibles POSIX, tels que UNIX , Linux , Mac OS X ou OpenVMS prennent en charge un mécanisme commun pour les fichiers de mappage de mémoire. Les systèmes d'exploitation Microsoft Windows prennent également en charge un groupe de fonctions API à cet effet, telles que CreateFileMapping () .

Certaines implémentations portables gratuites de fichiers mappés en mémoire pour Microsoft Windows et les plates-formes compatibles POSIX sont:

Le langage de programmation Java fournit des classes et des méthodes pour accéder aux fichiers mappés en mémoire, tels que FileChannel .

Le langage de programmation D prend en charge les fichiers mappés en mémoire dans sa bibliothèque standard (module std.mmfile).

Ruby a une gem (bibliothèque) appelée Mmap, qui implémente des objets fichier mappés en mémoire.

Depuis la version 1.6, Python a inclus un module mmap dans sa bibliothèque standard. Les détails du module varient selon que la plate-forme hôte est de type Windows ou Unix .

Pour Perl, il existe plusieurs modules disponibles pour les fichiers de mappage de mémoire sur le CPAN , tels que Sys :: Mmap et File :: Map .

Dans l'environnement d'exécution Microsoft .NET, P / Invoke peut être utilisé pour utiliser des fichiers mappés en mémoire directement via l' API Windows . L'accès géré (P / Invoke n'est pas nécessaire) aux fichiers mappés en mémoire a été introduit dans la version 4 du runtime (voir Fichiers mappés en mémoire ). Pour les versions précédentes, il existe des bibliothèques tierces qui fournissent des API gérées.

PHP a pris en charge les techniques de mappage mémoire dans un certain nombre de fonctions d'accès aux fichiers natives telles que file_get_contents () mais a supprimé cela dans 5.3 (voir le journal des révisions ).

Pour le langage de programmation R, il existe une bibliothèque sur CRAN appelée bigmemory qui utilise la bibliothèque Boost et fournit des tableaux sauvegardés mappés en mémoire directement dans R. Le paquet ff propose des vecteurs mappés en mémoire, des matrices, des tableaux et des trames de données.

Le langage de programmation J prend en charge les fichiers mappés en mémoire depuis au moins 2005. Il inclut la prise en charge des données de tableau en boîte et des fichiers de type de données unique. Le support peut être chargé à partir de 'data / jmf' Les moteurs de base de données Jdb et JD de J utilisent des fichiers mappés en mémoire pour les magasins de colonnes.

Les références