J'ai entendu (lu quelque part sur Internet) que mmap() est plus rapide que les E/S séquentielles. Est-ce correct? Si oui, pourquoi est-ce plus rapide ?
Cela peut être - il y a des avantages et des inconvénients, énumérés ci-dessous. Lorsque vous avez vraiment des raisons de vous en soucier, comparez toujours les deux .
Indépendamment de l'efficacité réelle des E/S, il y a des implications sur la façon dont le code de l'application suit le moment où il doit effectuer les E/S et effectue le traitement/la génération de données, ce qui peut parfois avoir un impact considérable sur les performances.
- mmap() ne lit pas séquentiellement.2) mmap() doit récupérer depuis le disque lui-même comme read() le fait3) La zone mappée n'est pas séquentielle - donc pas de DMA (?).
Donc, mmap() devrait en fait être plus lent que read() à partir d'un fichier ? Laquelle de mes hypothèses ci-dessus est fausse ?
-
est faux...
mmap()
attribue une région d'espace d'adressage virtuel correspondant au contenu du fichier ... chaque fois qu'une page de cet espace d'adressage est accessible, la RAM physique est trouvée pour sauvegarder les adresses virtuelles et le contenu du disque correspondant est défaillant dans cette RAM. Ainsi, l'ordre dans lequel les lectures sont effectuées à partir du disque correspond à l'ordre d'accès. C'est un mécanisme d'E/S "paresseux". Si, par exemple, vous deviez indexer dans une énorme table de hachage qui devait être lue à partir du disque, alorsmmap
le fichier et le début de l'accès signifient que les E / S du disque ne sont pas effectuées de manière séquentielle et peuvent donc entraîner un temps écoulé plus long jusqu'à ce que le fichier entier soit lu en mémoire, mais pendant ce temps, les recherches réussissent et un travail dépendant peut être entrepris, et si des parties du fichier ne sont jamais réellement nécessaires, elles ne sont pas lues (permettent la granularité des pages de disque et de mémoire, et que même lors de l'utilisation du mappage de la mémoire, de nombreux systèmes d'exploitation vous permettent de spécifier des conseils d'amélioration des performances / d'efficacité de la mémoire sur votre plan accéder aux modèles afin qu'ils puissent lire de manière proactive ou libérer de la mémoire de manière plus agressive en sachant que vous n'y reviendrez probablement pas). -
tout à fait vrai
-
"La zone cartographiée n'est pas séquentielle" est vague. Les régions mappées en mémoire sont "contiguës" (séquentielles) dans l'espace d'adressage virtuel. Nous avons discuté ci-dessus des E/S de disque séquentielles. Ou pensez-vous à autre chose ? Quoi qu'il en soit, alors que les pages sont défectueuses, elles peuvent en effet être transférées à l'aide de DMA.
De plus, il existe d'autres raisons pour lesquelles le mappage de la mémoire peut surpasser les E/S habituelles :
- il y a moins de copie :
- souvent, les routines au niveau du système d'exploitation et de la bibliothèque transmettent les données à travers un ou plusieurs tampons avant qu'elles n'atteignent un tampon spécifié par l'application, l'application alloue alors dynamiquement le stockage, puis copie du tampon d'E/S vers ce stockage afin que les données soient utilisables après le fichier lecture terminée
- le mappage de la mémoire permet (mais ne force pas) l'utilisation sur place (vous pouvez simplement enregistrer un pointeur et éventuellement une longueur)
- continuer à accéder aux données sur place risque d'augmenter les échecs de cache et/ou les échanges ultérieurs :le fichier/carte mémoire pourrait être plus verbeux que les structures de données dans lesquelles il pourrait être analysé, de sorte que les modèles d'accès aux données qu'il contient pourraient avoir plus de retards faute dans plus de pages de mémoire
- le mappage de la mémoire peut simplifier le travail d'analyse de l'application en permettant à l'application de traiter l'intégralité du contenu du fichier comme accessible, plutôt que de se soucier du moment où lire un autre tampon plein
- l'application s'en remet davantage à la sagesse du système d'exploitation concernant le nombre de pages qui se trouvent dans la RAM physique à un moment donné, partageant ainsi un cache disque à accès direct avec l'application
- comme les commentaires ci-dessous, "en utilisant le mappage de la mémoire, vous utilisez généralement moins d'appels système"
- si plusieurs processus accèdent au même fichier, ils doivent pouvoir partager les pages de sauvegarde physiques
Ce sont aussi les raisons pour lesquelles mmap
peut être plus lent - lisez le post de Linus Torvald ici qui parle de mmap
:
... les jeux de table de page avec la faute (et même juste le manque de TLB) la surcharge est facilement plus que le coût de la copie d'une page d'une manière agréable en continu...
Et d'un autre de ses messages :
- coûts d'installation et de démontage assez importants. Et je veux dire remarquable . Ce sont des choses comme suivre les tableaux de pages pour tout démapper proprement. C'est la comptabilité pour maintenir une liste de tous les mappages. C'est le vidage TLB nécessaire après avoir démappé des éléments.
- les défauts de page coûtent cher. C'est ainsi que le mappage est rempli, et c'est assez lent.
Linux a des "pages énormes" (donc une entrée TLB par 2 Mo, au lieu de 4 Ko) et même des pages énormes transparentes, où le système d'exploitation tente de les utiliser même si le code de l'application n'a pas été écrit pour les utiliser explicitement.
FWIW, la dernière fois que cela s'est produit pour moi au travail, l'entrée mappée en mémoire était 80 % plus rapide que fread
et al pour lire des enregistrements de base de données binaires dans une base de données propriétaire, sur Linux 64 bits avec des fichiers d'environ 170 Go.
mmap()
peut partager entre processus.- DMA sera utilisé dans la mesure du possible. Le DMA ne nécessite pas de mémoire contiguë :de nombreuses cartes haut de gamme prennent en charge le DMA par diffusion-collecte.
- La zone mémoire peut être partagée avec le cache de bloc du noyau si possible. Il y a donc copie par le bailleur.
- Mémoire pour
mmap
est alloué par le noyau, il est toujours aligné.