mmap () vs read ()
Je suis en train d'écrire un bloc ID3 tag editor en C. les tags ID3 sont généralement au début d'un mp3 fichier encodé, bien que plus âgé (version 1) les balises sont à la fin. L'app est conçu pour accepter un répertoire et cadre de la liste d'identification de la ligne de commande, puis répéter la structure de répertoire de mise à jour tous les tags ID3 qu'il trouve. L'utilisateur peut en outre choisir de supprimer toutes les anciennes (version 1) les balises. Une autre option est de simplement afficher les repères actuels, sans procéder à une mise à jour. Le répertoire peut contenir des fichiers 2 ou 2 millions de dollars. Si l'utilisateur le moyen de mettre à jour les fichiers, j'ai été la planification pour charger tout le fichier en mémoire, effectuer les mises à jour, puis de l'enregistrer (le fichier peut être renommé). Toutefois, si l'utilisateur le seul moyen pour imprimer le des tags ID3, puis en chargeant le fichier entier semble excessif. Après tout, le dossier peut être de 200 mo.
J'ai lu ce fil, qui était perspicace - mmap() par rapport à la lecture de blocs
Donc ma question est, quel est le moyen le plus efficace pour aller à ce sujet -- lire(), mmap() ou une combinaison des deux? Idées de conception de bienvenue.
TIA,
Andrew
Edit: C'est ma compréhension que mmap essentiellement les délégués du chargement d'un fichier dans la mémoire, à la mémoire virtuelle sous-système. Il me semble, la VMM serait hautement optimisé sur la plupart des systèmes, il est essentiel pour les performances du système.
source d'informationauteur J. Andrew Laughlin
Vous devez vous connecter pour publier un commentaire.
Cela dépend vraiment de ce que vous essayez de faire. Si tout ce que vous devez faire est de hop à un décalage de lire un petit tag,
read()
peut être plus rapide (mmap()
est de faire une partie assez complexe comptables internes). Si vous prévoyez de copier tous les 200 mo de MP3, cependant, ou d'analyse pour certains balise qui peuvent apparaître à un inconnu offset, puismmap()
est probablement le plus rapidement approche.Par exemple, si vous avez besoin de passer l'intégralité du fichier en bas de quelques centaines d'octets pour insérer une balise ID3, une approche simple serait de développer le fichier avec
ftruncate()
mmap le fichier, puismemmove()
le contenu vers le bas un peu. Ceci, cependant, va détruire le fichier si votre programme se bloque en cours d'exécution. Vous pouvez également copier le contenu du fichier dans un nouveau fichier - c'est un autre endroit où mmap() brille vraiment; vous pouvez simplementmmap()
l'ancien fichier, copier l'ensemble de ses données dans le nouveau fichier avec un seulwrite()
.En bref,
mmap()
est l'endroit idéal si vous êtes en train de faire une grande quantité d'e /s en termes de nombre total d'octets transférés; c'est parce qu'il réduit le nombre de copies nécessaires, et peut réduire considérablement le nombre de noyau d'entrées nécessaires pour la lecture des données mises en cache. Cependantmmap()
nécessite un minimum de deux voyages dans le noyau (trois si vous nettoyez le mappage lorsque vous avez terminé!) et un peu complexe du noyau interne de la comptabilité, et donc les frais fixes peuvent être élevés.read()
sur l'autre main implique un supplément de mémoire-de-la copie de la mémoire, et peut donc être inefficace pour les grandes opérations d'e/S, mais il est simple, et donc la charge fixe est relativement faible. En bref, l'utilisationmmap()
pour grand bloc I/O, etread()
oupread()
pour one-off, petit I/Os.Ne vous embêtez pas avec
mmap
à moins que votre code est liée à l'UC, notamment grâce à de nombreuses petites lectures et écritures.mmap
peut sembler agréable, mais ce n'est pas le génial pourquoi ce n'est pas tout le monde à l'aide de cette alternative, il ressemble.Étant donné que vous êtes recursing à travers potentiellement de grandes structures de répertoire, le goulot d'étranglement sera répertoire IO et de la concurrence.
mmap
ne va pas les aider.Update0
La lecture est liée à la question trouve cette réponse qui prend en charge mon expérience:
Si vous n'êtes pas normalement va être de streaming le fichier, puis de la traiter, mais plutôt autour de sauts (comme lire les étiquettes à l'avant et ensuite passer à la fin, etc.) alors je voudrais utiliser mmap tout simplement parce que votre code sera plus propre et plus facile à entretenir, traiter le fichier en tant que mémoire tampon de grande taille sans avoir à gérer la mise en mémoire tampon et la pagination de vous-même.
Comme il a été mentionné, si vous êtes du traitement d'un grand nombre de données d'I/O disque est susceptible de dominer votre traitement de toute façon. mmap peut être plus rapide que de le lire, mais raisonnable pour les implémentations, il est probable que pas beaucoup plus rapide, en particulier sur le matériel qui a toujours eu de plus en plus vite tandis que les disques qui ont été coincés à 7 200 et 10 000 TR /min pour des années et des années.
Alors, allez avec mmap et de rendre votre code simple et soigné.
Je ne sais pas si la norme POSIX fonctions résident à l'intérieur de ce que vous êtes autorisé ou vous aurez à utiliser pour le développement mais que penser de ces deux fonctions:
défini dans
unistd.h
qui peut être utilisé pour tronquer un fichier jusqu'à une longueur donnée. De cette façon, vous pouvez facilementJe ne suis pas sûr à propos de la performance, vous devez tester cette méthode, mais il doit charger beaucoup moins de choses à l'intérieur de la ram tout en offrant un senseful façon de faire.