Je pense que l'avantage est vraiment que vous réduisez la quantité de copie de données requise par rapport aux méthodes traditionnelles de lecture d'un fichier.
Si votre application peut utiliser les données «en place» dans un fichier mappé en mémoire, elle peut entrer sans être copiée; si vous utilisez un appel système (par exemple, pread () de Linux), cela implique généralement que le noyau copie les données de ses propres tampons dans l'espace utilisateur. Cette copie supplémentaire prend non seulement du temps, mais diminue l'efficacité des caches du processeur en accédant à cette copie supplémentaire des données.
Si les données doivent réellement être lues à partir du disque (comme dans les E / S physiques), alors le système d'exploitation doit toujours les lire, une erreur de page n'est probablement pas meilleure en termes de performances qu'un appel système, mais si elles pas (c'est-à-dire déjà dans le cache du système d'exploitation), les performances devraient en théorie être bien meilleures.
En revanche, il n'y a pas d'interface asynchrone pour les fichiers mappés en mémoire - si vous essayez d'accéder à une page qui n'est pas mappée, cela génère une erreur de page, puis fait attendre le thread pour les E / S.
L'inconvénient évident des fichiers mappés en mémoire est sur un système d'exploitation 32 bits - vous pouvez facilement manquer d'espace d'adressage.
J'ai utilisé un fichier mappé en mémoire pour implémenter une fonction de «saisie semi-automatique» pendant que l'utilisateur tape. J'ai plus d'un million de références de produits stockées dans un seul fichier d'index. Le fichier contient des informations d'en-tête typiques, mais la majeure partie du fichier est un tableau géant d'enregistrements de taille fixe triés sur le champ clé.
Au moment de l'exécution, le fichier est mappé en mémoire, converti en un tableau de
C
stylestruct
, et nous effectuons une recherche binaire pour trouver les numéros de pièce correspondants lorsque l'utilisateur tape. Seules quelques pages de mémoire du fichier sont réellement lues à partir du disque - quelles que soient les pages touchées lors de la recherche binaire.la source
Les fichiers mappés en mémoire peuvent être utilisés pour remplacer l'accès en lecture / écriture ou pour prendre en charge le partage simultané. Lorsque vous les utilisez pour un mécanisme, vous obtenez également l'autre.
Plutôt que de rechercher, d'écrire et de lire dans un fichier, vous le mappez en mémoire et accédez simplement aux bits où vous vous attendez à ce qu'ils soient.
Cela peut être très pratique et, selon l'interface de la mémoire virtuelle, améliorer les performances. L’amélioration des performances peut se produire car le système d’exploitation gère désormais cette ancienne «E / S de fichier» ainsi que tous vos autres accès à la mémoire par programmation, et peut (en théorie) exploiter les algorithmes de pagination et ainsi de suite qu’il utilise déjà pour prendre en charge mémoire virtuelle pour le reste de votre programme. Cela dépend cependant de la qualité de votre système de mémoire virtuelle sous-jacent. Des anecdotes que j'ai entendues dire que les systèmes de mémoire virtuelle Solaris et * BSD peuvent montrer de meilleures améliorations de performances que le système VM de Linux - mais je n'ai pas de données empiriques pour étayer cela. YMMV.
La concurrence entre en jeu lorsque vous considérez la possibilité que plusieurs processus utilisent le même «fichier» via la mémoire mappée. Dans le modèle de lecture / écriture, si deux processus écrivaient dans la même zone du fichier, vous pourriez être à peu près assuré que l'une des données du processus arriverait dans le fichier, écrasant les données de l'autre processus. Vous obtiendrez l'un ou l'autre - mais pas un mélange étrange. Je dois admettre que je ne suis pas sûr qu'il s'agisse d'un comportement imposé par une norme, mais c'est quelque chose sur lequel vous pouvez compter. (C'est en fait une bonne question de suivi!)
Dans le monde cartographié, en revanche, imaginez deux processus à la fois «d'écriture». Ils le font en effectuant des «magasins de mémoire», ce qui entraîne la pagination des données sur le disque par le système d'exploitation - éventuellement. Mais en attendant, on peut s'attendre à ce que des écritures se chevauchent.
Voici un exemple. Disons que j'ai deux processus écrivant tous les deux 8 octets à l'offset 1024. Le processus 1 écrit «11111111» et le processus 2 écrit «22222222». S'ils utilisent des E / S de fichier, alors vous pouvez imaginer, au fond de l'O / S, qu'il y a un tampon plein de 1 et un tampon plein de 2, tous deux dirigés au même endroit sur le disque. L'un d'eux y arrivera le premier, et l'autre une seconde. Dans ce cas, le second l'emporte. Cependant , si j'utilise l'approche des fichiers mappés en mémoire, le processus 1 va aller dans une mémoire de 4 octets, suivie d'une autre mémoire de 4 octets (supposons que ce n'est pas la taille maximale de la mémoire de stockage). Le processus 2 fera la même chose. En fonction du moment où les processus s'exécutent, vous pouvez vous attendre à voir l'un des éléments suivants:
La solution à cela est d'utiliser l'exclusion mutuelle explicite - ce qui est probablement une bonne idée de toute façon. Vous vous reposiez en quelque sorte sur l'O / S pour faire "la bonne chose" dans le cas d'E / S de fichier en lecture / écriture, de toute façon.
La primitive d'exclusion mutuelle de classification est le mutex. Pour les fichiers mappés en mémoire, je vous suggère de regarder un mutex mappé en mémoire, disponible en utilisant (par exemple) pthread_mutex_init ().
Modifier avec un seul piège: lorsque vous utilisez des fichiers mappés, il est tentant d'incorporer des pointeurs vers les données dans le fichier, dans le fichier lui-même (pensez à la liste liée stockée dans le fichier mappé). Vous ne voulez pas faire cela, car le fichier peut être mappé à différentes adresses absolues à des moments différents ou dans différents processus. Utilisez plutôt des décalages dans le fichier mappé.
la source
La concurrence serait un problème. L'accès aléatoire est plus facile Les performances sont bonnes à excellentes. Facilité d'utilisation. Pas aussi bon. Portabilité - pas si chaud.
Je les ai utilisés sur un système solaire il y a longtemps, et ce sont mes pensées.
la source