Question

Les environnements POSIX offrent au moins deux méthodes pour accéder aux fichiers. Il existe les appels système standard open () , read () , write () et amis, mais vous pouvez également utiliser mmap () pour mapper le fichier dans la mémoire virtuelle.

Quand est-il préférable d'utiliser l'un plutôt que l'autre? Quels sont leurs avantages individuels qui méritent d’inclure deux interfaces?

Était-ce utile?

La solution

mmap est idéal si plusieurs processus accèdent en lecture seule aux données à partir du même fichier, ce qui est courant dans le type de système de serveur que j'écris. mmap permet à tous ces processus de partager les mêmes pages de mémoire physique, économisant ainsi beaucoup de mémoire.

mmap permet également au système d'exploitation d'optimiser les opérations de pagination. Par exemple, considérons deux programmes; programme A qui lit un fichier de 1 Mo dans un tampon créant avec malloc et programme B qui mappe le fichier de 1 Mo en mémoire. Si le système d'exploitation doit permuter une partie de la mémoire de A, il doit écrire le contenu de la mémoire tampon à permuter avant de pouvoir réutiliser la mémoire. Dans le cas de B, toutes les pages mmap'd non modifiées peuvent être réutilisées immédiatement car le système d'exploitation sait comment les restaurer à partir du fichier existant à partir duquel elles ont été copiées. (Le système d'exploitation peut détecter les pages non modifiées en marquant initialement les pages mmap'd en écriture comme étant en lecture seule et en détectant les erreurs de segment, comme dans la stratégie de copie sur écriture).

mmap est également utile pour la communication entre processus. Vous pouvez mapper un fichier en lecture / écriture dans les processus devant communiquer, puis utiliser des primitives de synchronisation dans la région mmap'd (c’est à cela que sert l’indicateur MAP_HASSEMAPHORE).

Un emplacement mmap peut être gênant si vous devez travailler avec de très gros fichiers sur une machine 32 bits. En effet, mmap doit trouver un bloc d'adresses contigu dans l'espace d'adressage de votre processus suffisamment volumineux pour s'adapter à toute la plage du fichier en cours de mappage. Cela peut devenir un problème si votre espace d'adressage devient fragmenté, vous pouvez ainsi disposer de 2 Go d'espace libre, mais aucune plage individuelle ne peut contenir un mappage de fichier de 1 Go. Dans ce cas, vous devrez peut-être mapper le fichier en morceaux plus petits que vous ne le souhaitez.

Un autre inconvénient potentiel de l'utilisation de mmap en remplacement de la lecture / écriture est que vous devez commencer votre mappage sur des décalages de la taille de la page. Si vous souhaitez simplement obtenir des données au décalage X, vous devez corriger ce décalage afin qu'il soit compatible avec mmap.

Enfin, la lecture / écriture est la seule façon dont vous pouvez travailler avec certains types de fichiers. mmap ne peut pas être utilisé sur des choses comme des pipes et des ttys.

Autres conseils

Un domaine dans lequel mmap () n’était pas un avantage était celui de la lecture de petits fichiers (moins de 16 Ko). La surcharge de page liée à la lecture de l'ensemble du fichier était très élevée par rapport à un simple appel système read (). Cela est dû au fait que le noyau peut parfois satisfaire entièrement une lecture dans votre tranche de temps, ce qui signifie que votre code ne disparaît pas. Avec une erreur de page, il semblait plus probable qu'un autre programme soit planifié, ce qui rendait l'opération de fichier plus longue.

mmap présente l'avantage lorsque vous avez un accès aléatoire aux gros fichiers. Un autre avantage est que vous y accédez avec des opérations de mémoire (mémoire, arithmétique de pointeur), sans vous soucier de la mise en mémoire tampon. Les E / S normales peuvent parfois être assez difficiles lorsque vous utilisez des tampons lorsque vous avez des structures plus grandes que votre tampon. Le code à traiter est souvent difficile à obtenir, mmap est généralement plus facile. Cela dit, il y a certaines interruptions lorsque vous utilisez mmap . Comme on l'a déjà mentionné, la configuration de mmap est assez coûteuse. Il est donc intéressant de ne l'utiliser que pour une taille donnée (variant d'une machine à l'autre).

Pour les accès séquentiels purs au fichier, ce n'est pas toujours la meilleure solution, bien qu'un appel approprié à madvise puisse atténuer le problème.

Vous devez faire attention aux restrictions d'alignement de votre architecture (SPARC, itanium). En lecture / écriture des entrées / sorties, les tampons sont souvent correctement alignés et ne sont pas interceptés lors du déréférencement d'un pointeur converti.

Vous devez également veiller à ne pas accéder en dehors de la carte. Cela peut facilement arriver si vous utilisez des fonctions de chaîne sur votre carte et que votre fichier ne contient pas un \ 0 à la fin. Il fonctionnera la plupart du temps lorsque la taille de votre fichier ne représente pas un multiple de la taille de la page, car la dernière page est remplie avec 0 (la zone mappée a toujours la taille d'un multiple de la taille de votre page).

Outre d'autres réponses intéressantes, une citation de Programmation système Linux écrite de Robert Love, expert de Google:

  

Avantages de mmap ()

     

La manipulation de fichiers via mmap () présente de nombreux avantages par rapport à la   appels système standard read () et write () . Parmi eux:

     
      
  • La lecture et l’écriture dans un fichier mappé en mémoire évite la   copie parasite apparaissant lors de l'utilisation du système read () ou write ()   appels, où les données doivent être copiées vers et depuis un tampon d’espace utilisateur.

  •   
  • Hormis les éventuels défauts de page, la lecture et l'écriture dans un fichier mappé en mémoire n'entraînent aucun appel système ni aucune modification de contexte.   aérien. C'est aussi simple que d'accéder à la mémoire.

  •   
  • Lorsque plusieurs processus mappent le même objet en mémoire, les données sont partagées entre tous les processus. Lecture seule et écriture partagée   les mappages sont partagés dans leur intégralité; mappages privés en écriture ont   leurs pages non encore COW (copie sur écriture) partagées.

  •   
  • La recherche autour du mappage implique des manipulations triviales de pointeur. L'appel système lseek () n'est pas nécessaire.

  •   
     

Pour ces raisons, mmap () est un choix judicieux pour de nombreuses applications.

     

Inconvénients de mmap ()

     

Il y a quelques points à garder à l'esprit lors de l'utilisation de mmap () :

     
      
  • Les mappages de mémoire sont toujours un nombre entier de pages. Ainsi, la différence entre la taille du fichier de sauvegarde et un   nombre entier de pages est " gaspillé " comme espace lâche. Pour les petits fichiers, un   un pourcentage important de la cartographie peut être gaspillé. Par exemple, avec   Pages de 4 Ko, un mappage sur 7 octets gaspille 4 089 octets.

  •   
  • Les mappages de mémoire doivent tenir dans l'espace d'adressage du processus. Avec un espace d’adresse 32 bits, un très grand nombre de mappages de tailles différentes   peut entraîner une fragmentation de l'espace d'adressage, rendant difficile la   trouver de grandes régions contiguës gratuites. Ce problème, bien sûr, est beaucoup   moins apparente avec un espace d’adresse 64 bits.

  •   
  • La création et la maintenance des mappages de mémoire et des structures de données associées à l'intérieur du noyau entraînent une surcharge. Cette surcharge est   généralement éliminée par l'élimination de la double copie mentionnée à   la section précédente, en particulier pour les plus grandes   fichiers.

  •   
     

Pour ces raisons, les avantages de mmap () sont plus largement réalisés   lorsque le fichier mappé est volumineux (et donc tout espace perdu est un petit   pourcentage du mappage total), ou lorsque la taille totale du mappé   Le fichier est divisible par la taille de la page (il n’ya donc pas de gaspillage).   espace).

Le mappage de la mémoire offre un avantage considérable en termes de vitesse par rapport aux E / S traditionnelles. Il permet au système d'exploitation de lire les données du fichier source au fur et à mesure que les pages du fichier mappé en mémoire sont touchées. Cela fonctionne en créant des pages défectueuses que le système d'exploitation détecte, puis charge automatiquement les données correspondantes à partir du fichier.

Cela fonctionne de la même manière que le mécanisme de pagination et est généralement optimisé pour les E / S rapides en lisant les données sur les limites et les tailles de pages système (généralement 4 Ko) - une taille pour laquelle la plupart des caches de système de fichiers sont optimisés.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top