82 votes

Quels sont les avantages de fichiers mappés en mémoire?

J'ai fait des recherches sur les fichiers mappés en mémoire pour un projet, et apprécie les pensées des gens qui l'ont utilisé avant, ou de décidé de les utiliser, et pourquoi?

En particulier, je suis préoccupé par la suivante, par ordre d'importance:

  • la simultanéité
  • d'accès aléatoire
  • performance
  • la facilité d'utilisation
  • la portabilité

52voto

MarkR Points 37178

Je pense que l'avantage est vraiment que vous réduisez la quantité de copies des données nécessaires sur les méthodes traditionnelles de la lecture d'un fichier.

Si votre application peut utiliser les données "en place" dans un fichier mappé en mémoire, il peut venir sans être copié; si vous utilisez un système d'appel (par exemple, Linux pread ()), puis qui implique généralement le noyau de copier les données à partir de ses propres tampons dans l'espace utilisateur. Cette copie supplémentaire non seulement prend du temps, mais diminue l'efficacité de la CPU caches par l'accès à cette copie supplémentaire des données.

Si les données doivent être lues à partir du disque (comme en physique I/O), alors le système d'exploitation a encore de les lire dans, un défaut de page n'est probablement pas une meilleure performance qu'un appel système, mais si ils ne le font pas (c'est à dire déjà dans le cache du système d'exploitation), les performances devraient en théorie être beaucoup mieux.

Sur le revers de la médaille, il n'y a pas d'interface asynchrone de fichiers mappés en mémoire - si vous tentez d'accéder à une page qui n'est pas mappé, il génère une erreur de page puis fait la fil d'attente pour l'I/O.


L'inconvénient évident pour les fichiers mappés en mémoire est sur un 32 bits de l'OS que vous pouvez facilement exécuter hors de l'espace d'adressage.

46voto

Brian Ensink Points 7579

J'ai utilisé un fichier mappé en mémoire pour mettre en œuvre une "auto-complete" lorsque l'utilisateur est en train de taper. J'ai bien plus de 1 million de numéros de pièce du produit stocké dans un seul fichier d'index. Le fichier a quelques informations d'en-tête, mais la majeure partie du fichier est un tableau géant de taille fixe enregistrements triés sur le champ de clé.

Au moment de l'exécution le fichier mappé en mémoire, converti en C-style struct tableau, et nous faisons une recherche binaire pour trouver la correspondance des numéros de pièce que l'utilisateur tape. Seulement quelques pages de mémoire du fichier est lu à partir du disque -- selon les pages sont frappés au cours de la recherche binaire.

  • La simultanéité - j'ai eu un problème de mise en œuvre où il serait parfois la mémoire de la carte le fichier plusieurs fois dans le même espace de processus. C'était un problème que je me souviens, parce que parfois, le système ne pouvait pas trouver un assez grand bloc de mémoire virtuelle pour mapper le fichier. La solution a été la seule carte que le fichier une fois et paf tous les appels à elle. Rétrospectivement, à l'aide d'une pleine soufflé service Windows aurait été cool.
  • Accès aléatoire - Le binaire de recherche est certainement un accès direct et rapide comme l'éclair
  • La Performance de La recherche est extrêmement rapide. Comme les utilisateurs de type, une fenêtre contextuelle affiche une liste de correspondance des numéros de pièce du produit, la liste se rétrécit comme ils continuent à taper. Il n'y a pas remarqué de lag lors de la frappe.

22voto

bog Points 1160

Les fichiers mappés en mémoire peuvent être utilisées pour remplacer les accès en lecture/écriture, ou à l'appui simultané de partage. Lorsque vous les utilisez pour un mécanisme, vous obtenez de l'autre.

Plutôt que de lseeking et de l'écriture et de la lecture dans un fichier, vous carte dans la mémoire et d'accéder simplement à l'bits où vous vous attendez à être.

Cela peut être très pratique, et en fonction de la mémoire virtuelle de l'interface permet d'améliorer les performances. L'amélioration des performances peut se produire parce que le système d'exploitation est de gérer cet ancien "fichier I/O" ainsi que tous les autres programmes d'accès à la mémoire, et peut (en théorie) de tirer parti de la pagination des algorithmes et ainsi de suite que c'est déjà l'appui de la mémoire virtuelle pour le reste de votre programme. Il ne, cependant, dépend de la qualité de votre sous-jacents au système de mémoire virtuelle. Des Anecdotes, j'ai entendu dire que le Solaris et *BSD mémoire virtuelle systèmes peuvent montrer de meilleures améliorations de performance que le système VM Linux--mais je n'ai pas de données empiriques pour étayer cette. YMMV.

La simultanéité entre dans l'image lorsque vous considérez la possibilité de multiples processus à l'aide de la même "fichier" par le biais de la mémoire mappée. Dans la lecture/l'écriture du modèle, si deux processus a écrit à la même zone du fichier, vous pouvez être à peu près assuré que l'un des processus les données arrivent dans le fichier, en écrasant les autres processus de données. Vous obtenez l'un ou de l'autre, mais pas un peu bizarre brassage. Je dois admettre que je ne suis pas sûr de savoir si ce comportement est mandaté par aucune norme, mais c'est quelque chose que vous pouvait très bien compter. (C'est en fait bien suivi la question!)

Dans le mappé monde, en revanche, imaginez deux processus à la fois "l'écriture". Ils le font en faisant "de mémoire", qui est le résultat de l'O/S pagination des données sur le disque--par la suite. Mais en attendant, le chevauchement des écritures peut être prévu de se produire.

Voici un exemple. Dire que j'ai deux processus à la fois l'écrit 8 octets au décalage 1024. Processus 1 est écrit '11111111' et 2 de processus est écrit "22222222'. Si elles utilisent des e/S sur fichier, puis vous pouvez l'imaginer, au plus profond de l'O/S, il y a un tampon plein de 1s, et un tampon plein de 2s, à la fois dirigé vers le même emplacement sur le disque. L'un d'eux va y arriver tout d'abord, et de l'autre une seconde. Dans ce cas, la seconde que l'on gagne. Cependant, si je suis en utilisant le fichier mappé en mémoire de l'approche, les processus de 1, aller à un magasin de mémoire de 4 octets, suivie par une autre banque de mémoire de 4 octets (supposons que pas la quantité maximale de mémoire taille de la banque). Processus 2 va faire la même chose. Basée sur le moment où le processus, vous pouvez vous attendre à voir l'un des suivants:

11111111
22222222
11112222
22221111

La solution pour cela est d'utiliser explicites d'exclusion mutuelle, - ce qui est probablement une bonne idée en tout cas. Vous étiez en sorte de s'appuyer sur l'O/S à faire "la chose" dans la lecture/écriture de fichier I/O des cas, de toute façon.

Le classement de l'exclusion mutuelle primitive est le mutex. Pour les fichiers mappés en mémoire, je vous suggère de regarder un mappé en mémoire de mutex, disponible en utilisant (par exemple) pthread_mutex_init().

Modifier avec un gotcha: Lorsque vous utilisez des fichiers mappés, il est tentant d'intégrer des pointeurs vers les données dans le fichier, dans le fichier lui-même (pensez lié liste stockée dans le fichier mappé). Vous ne voulez pas le faire, car le fichier peut être mappé à différentes adresses absolues à des moments différents, ou dans des processus différents. Au lieu de cela, utiliser des décalages dans le fichier mappé.

1voto

Paul Nathan Points 22910

La simultanéité serait un problème. D'accès aléatoire est plus facile La Performance est de bonne à excellente. La facilité d'utilisation. Pas aussi bon. Portabilité - pas si chaud.

Je l'ai utilisé sur un système Sun il y a longtemps, et ce sont mes pensées.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X