mmap et l'utilisation de la mémoire
Je suis en train d'écrire un programme qui reçoit d'énormes quantités de données (en morceaux de différentes tailles à partir du réseau, les processus et les écrit dans la mémoire. Depuis quelques oeuvres de données peut être très grande, ma démarche actuelle est de limiter la taille de la mémoire tampon utilisée. Si une pièce est plus grande que le maximum de la taille de la mémoire tampon, j'ai écrit les données dans un fichier temporaire et, plus tard, de lire le fichier en morceaux pour le traitement et le stockage permanent.
Je me demande si cela peut être amélioré. J'ai lu à propos de mmap pour un moment, mais je ne suis pas à cent pour cent sûr que si il peut m'aider. Mon idée est d'utiliser mmap pour la lecture du fichier temporaire. Est-ce à aider de quelque façon? La principale chose que je suis inquiète, c'est qu'occasionnellement un grand morceau de données ne doit pas remplir mon mémoire principale entraînant tout le reste pour être échangé.
Aussi, pensez-vous que l'approche avec des fichiers temporaires est utile? Même si je dois faire ça ou, peut-être, devrais-je faire confiance à linux, le gestionnaire de mémoire pour faire le travail pour moi? Ou dois-je faire quelque chose d'autre?
source d'informationauteur Elektito | 2012-04-24
Vous devez vous connecter pour publier un commentaire.
Mmap peut vous aider à certains égards, je vais vous expliquer avec des exemples hypothétiques:
Première chose: disons que vous êtes à court de mémoire, et votre application qui ont un 100MB morceau de malloc ed mémoire bénéficiez de 50% de celui-ci d'échanger, ce qui signifie que le système d'exploitation dû écrire 50 MO pour le fichier d'échange, et si vous avez besoin de le lire, que vous avez écrit, occupé et puis le lire à nouveau 50MO de votre fichier d'échange.
Dans le cas où la mémoire était juste mmap ed, le système d'exploitation ne sera pas écrire ce morceau de l'information pour le fichier d'échange (comme il sait que que les de données est identique au fichier lui-même), au lieu de cela, il suffit de gratter 50 mo d'informations (encore une fois: à supposer que vous n'avez pas écrit quoi que ce soit pour l'instant) et c'est tout. Si jamais vous avez besoin que la mémoire à relire, l'OS va chercher le contenu non à partir du fichier d'échange, mais à partir du fichier d'origine que vous avez mmaped, donc, si tout autre programme a besoin de 50 mo de swap, ils sont disponibles. Il ya aussi pas de frais généraux grâce à la manipulation de fichier d'échange à tous.
Disons que vous avez lu un de 100 mo bloc de données, et en fonction de l'initiale de 1 mo de données d'en-tête, les informations que vous souhaitez est situé au décalage 75 MO, de sorte que vous n'avez pas besoin de quoi que ce soit entre 1~74.9 MO! Vous l'avez lu pour rien mais pour rendre votre code plus simple. Avec mmap, vous pourrez seulement lire les données que vous avez réellement accessible (arrondi à 4 ko, ou l'OS de la taille de page, qui est la plupart du temps 4ko), de sorte qu'il serait lu que le premier et le 75e MO. Je pense que c'est très dur de faire plus simple et plus efficace, pour éviter de disque lecture que mmaping fichiers.
Et si par quelque raison vous avez besoin de données au décalage 37MB, vous pouvez simplement l'utiliser! Vous n'avez pas à mmap à nouveau, comme l'ensemble du dossier est accessible dans la mémoire (bien sûr limitée par votre processus' espace mémoire).
Tous les fichiers mmap ed sont sauvegardés par eux-mêmes, pas par le fichier d'échange, le fichier d'échange est d'accorder des données qui n'ont pas un fichier de sauvegarde, qui est généralement de données malloc ed ou des données qui sont sauvegardées par un fichier, mais qu'il a été modifié et ne peut pas/ne peut] être écrite en arrière avant que le programme ne raconte en fait l'OS de le faire via une msync appel.
Méfiez-vous que vous n'avez pas besoin de carte, l'ensemble du fichier en mémoire, vous pouvez mapper n'importe quel montant (2e argument est "size_t length") à partir de n'importe quel lieu (6 arg - "off_t offset"), mais à moins que votre fichier est susceptible d'être énorme, vous pouvez en toute sécurité la carte de 1 go de données sans crainte, même si le système n'a que des packs de 64 mo de mémoire physique, mais c'est pour la lecture, si vous prévoyez d'écrire, alors vous devez être plus prudent et carte seulement les choses que vous avez besoin.
Fichiers de mappage de vous aideront à rendre votre code plus simple (vous avez déjà le contenu du fichier sur la mémoire, prêt à l'emploi, avec beaucoup moins de surcharge de la mémoire puisqu'il n'est pas anonyme de mémoire) et plus rapide (vous n'aurez qu'à lire les données de votre programme d'accès).
Le principal avantage de mmap avec de gros fichiers est de partager le même mappage de mémoire entre deux fichiers ou plus: si vous pamm avec
MAP_SHARED
il sera chargé en mémoire une seule fois pour tous les processus qui permettront d'utiliser les données avec la mémoire de l'épargne.Mais autant que je sache , mmap les cartes de tout le fichier en mémoire (Ici vous pouvez trouver des exemples de la façon dont mmap échoue avec les fichiers de plus de physique mem + espace de swap.) donc, si vous avez accès au fichier à partir d'un seul processus, il ne sera pas vous aider avec la physique, la consommation de mémoire.
Je crois mmap ne nécessite pas toutes les données en mémoire au même moment est - il utilise le cache de la page pour garder récemment utilisé des pages en mémoire, et le reste sur le disque.
Si vous êtes à la lecture d'un morceau à la fois, à l'aide d'un fichier temporaire ne sera probablement pas vous aider, mais si vous êtes la lecture de plusieurs morceaux simultanément en utilisant plusieurs threads, processus, ou à l'aide de select/poll, alors qu'il le pourrait.