Question

Je suis en train de travailler sur un programme de traitement de fichiers pouvant être 100 go ou plus en taille.Les fichiers contiennent des ensembles d'enregistrements de longueur variable.J'ai une première mise en œuvre et en cours d'exécution et je suis maintenant à la recherche pour améliorer les performances, en particulier à faire des I/O de manière plus efficace depuis le fichier d'entrée sera scannée à de nombreuses reprises.

Est-il une règle de pouce pour l'aide mmap() rapport à la lecture dans les blocs via C++ fstream bibliothèque?Ce que je voudrais faire est de lire les gros pâtés de maisons de disque dans un buffer, les processus, les dossiers complets à partir de la mémoire tampon, puis en lire plus.

L' mmap() code pourrait être potentiellement très salissant depuis mmap'd blocs besoin de mentir sur la page de la taille des frontières (à ma connaissance) et les enregistrements pourraient potentiellement comme à travers les limites de la page.Avec fstreams, je cherche juste le début d'un enregistrement et commencer à lire à nouveau, comme nous ne sommes pas limités à la lecture des blocs qui se trouvent sur la page de la taille des frontières.

Comment puis-je choisir entre ces deux options, sans réellement la rédaction d'une mise en œuvre complète de la première?Toutes les règles de base (p. ex., mmap() est 2x plus rapide) ou de simples tests?

Était-ce utile?

La solution

J'ai essayé de trouver le mot de la fin sur mmap / performances de lecture sur Linux et je suis tombé sur un post-nice (lien) sur le noyau Linux liste de diffusion.C'est à partir de 2000, donc il y a eu de nombreuses améliorations à l'interface IO et de la mémoire virtuelle du noyau depuis, mais il explique bien la raison pour laquelle mmap ou read peut-être plus rapide ou plus lent.

  • Un appel à mmap a plus de ressources que l' read (tout comme epoll a plus de ressources que l' poll, qui a plus de ressources que l' read).Évolution des mappages de mémoire virtuelle est un très coûteux opération sur certains processeurs pour les mêmes raisons que la commutation entre les différents processus est coûteux.
  • Le système e / s peut déjà utiliser le cache de disque, donc, si vous lisez un fichier, vous serez frappé de la mémoire cache ou manquer peu importe la méthode que vous utilisez.

Cependant,

  • Cartes mémoire sont généralement plus rapides pour un accès aléatoire, surtout si vos modèles d'accès sont rares et imprévisibles.
  • La mémoire des cartes vous permettent de garder à l'aide de pages à partir du cache jusqu'à ce que vous sont effectuées.Cela signifie que si vous utilisez un fichier lourdement pour une longue période de temps, puis le fermer et le rouvrir, les pages doivent encore être mis en cache.Avec read, votre fichier peut avoir été supprimées du cache il y a des siècles.Cela ne s'applique pas si vous utilisez un fichier et de le jeter immédiatement il.(Si vous essayez de mlock pages juste pour les garder dans le cache, vous êtes en essayant de déjouer le cache disque et ce genre de bêtises rarement aide à la performance du système).
  • La lecture d'un fichier directement est très simple et rapide.

La discussion de mmap/lire me rappelle de deux autres discussions sur le rendement:

  • Certains programmeurs Java ont été choqués de découvrir que non bloquantes I/O est souvent plus lent que le blocage des I/O, ce qui est tout à fait logique si vous savez que non bloquantes I/O nécessite de faire plus d'appels.

  • Un autre réseau programmeurs ont été choqués d'apprendre que epoll est souvent plus lent que poll, ce qui est logique si vous savez que la gestion de la epoll oblige à faire plus d'appels.

Conclusion: Utilisation de cartes mémoire si vous accédez à des données au hasard, le garder pour une longue période de temps, ou si vous savez que vous pouvez le partager avec d'autres processus (MAP_SHARED n'est pas très intéressant si il n'y a pas de partage).Lire les fichiers normalement, si vous accédez à des données de manière séquentielle ou de le rejeter après la lecture.Et si la méthode rend votre programme moins complexe, que.Pour beaucoup de monde réel des cas, il n'y a pas de moyen sûr pour montrer l'un est plus rapide sans le test de votre application réelle et non PAS un indice de référence.

(Désolé pour le nécro qui pratiquent cette question, mais je cherchais une réponse à cette question a cessé de venir dans le haut des résultats de Google.)

Autres conseils

Le principal coût de performance va être d'i/o disque."mmap()" est certainement plus rapide que istream, mais la différence peut ne pas être sensible parce que les i/o disque va dominer votre temps.

J'ai essayé de Ben Collins du fragment de code (voir ci-dessus/ci-dessous), afin de tester son affirmation que "mmap() est façon plus rapide" et n'a trouvé aucune différence mesurable.Voir mes commentaires sur sa réponse.

Je serais certainement pas recommander séparément mmap avec chaque enregistrement, à son tour, à moins que votre "dossiers" sont énormes - ce serait horriblement lent, nécessitant 2 appels système pour chaque enregistrement et peut-être perdre la page du disque, de la mémoire cache.....

Dans votre cas, je pense que mmap(), istream et le faible niveau de open()/lecture() appels seront sur le même.Je recommande mmap() dans ces cas:

  1. Il est en accès aléatoire (non séquentiel) dans le fichier, ET
  2. le tout s'adapte confortablement dans la mémoire OU il y a de la localité de référence dans le fichier, de sorte que certaines pages peuvent être mappés et les autres pages du tracé.De cette façon, le système d'exploitation utilise la RAM disponible pour un maximum de profit.
  3. OU si plusieurs processus de lecture/travail sur le même fichier mmap() est fantastique parce que les processus partagent tous les mêmes pages physiques.

(btw, j'adore mmap()/MapViewOfFile()).

mmap est façon plus rapide.Vous pouvez écrire une simple référence pour le prouver à vous-même:

char data[0x1000];
std::ifstream in("file.bin");

while (in)
{
  in.read(data, 0x1000);
  // do something with data
}

contre:

const int file_size=something;
const int page_size=0x1000;
int off=0;
void *data;

int fd = open("filename.bin", O_RDONLY);

while (off < file_size)
{
  data = mmap(NULL, page_size, PROT_READ, 0, fd, off);
  // do stuff with data
  munmap(data, page_size);
  off += page_size;
}

Clairement, je suis en laissant de côté les détails (comme la façon de déterminer quand vous avez atteint la fin du fichier dans le cas où votre fichier n'est pas un multiple de page_size, par exemple), mais ça ne devrait pas être beaucoup plus compliqué que cela.

Si vous le pouvez, vous pouvez essayer de briser vos données dans plusieurs fichiers qui peuvent être mmap()-ed dans son ensemble plutôt que dans la partie (beaucoup plus simple).

Il y A quelques mois j'ai eu une demi-cuite de la mise en œuvre d'un coulissante de la fenêtre de mmap()-ed classe de flux pour boost_iostreams, mais personne ne se souciait et je me suis occupé avec d'autres choses.Malheureusement, j'ai supprimé des archives de vieux projets non achevés il y a quelques semaines, et qui a été l'une des victimes :-(

Mise à jour:Je dois également ajouter l'avertissement que ce test sera assez différent dans Windows parce que Microsoft a mis en place un astucieux fichier cache qui réalise la plupart de ce que vous feriez avec mmap en premier lieu.I. e., souvent d'accéder à des fichiers, vous pouvez juste faire std::ifstream.read (), et il serait aussi vite que mmap, car le fichier de cache aurais déjà fait une projection en mémoire pour vous, et c'est transparent.

Dernière Mise À Jour:Regardez, les gens:à travers un grand nombre de différentes combinaisons de plate-forme de l'OS et de la norme des bibliothèques et des disques et de la mémoire des hiérarchies, je ne peux pas dire à certains que l'appel système mmap, considéré comme une boîte noire, toujours toujours toujours être sensiblement plus rapide read.Ce n'était pas exactement mon intention, même si mes mots pourraient être interprétées de cette façon. En fin de compte, mon point était que memory-mapped i/o est généralement plus rapide que d'octets d'e/s;cela est encore vrai.Si vous trouvez expérimentalement qu'il n'y a pas de différence entre les deux, la seule explication qui me semble raisonnable, c'est que votre plate-forme met en œuvre de carte mémoire sous les couvertures dans une manière qui est avantageux pour la performance des appels à read.La seule façon d'être absolument certain que vous êtes à l'aide de memory-mapped i/o dans un portable est d'utiliser mmap.Si vous n'avez pas de soins sur la portabilité et vous pouvez compter sur les caractéristiques de votre cible plates-formes, puis à l'aide de read peut être adapté sans pour autant sacrifier sensiblement les performances.

Edit pour nettoyer la liste des réponses: @jbl:

la fenêtre coulissante mmap sons intéressant.Pouvez-vous en dire un peu plus à ce sujet?

Assurez-vous - j'ai écrit une bibliothèque C++ pour Git (un libgit++, si vous voulez), et j'ai rencontré un problème similaire à ceci:J'avais besoin d'être en mesure d'ouvrir large (très large) des fichiers et de ne pas avoir le rendement total de chien (comme elle le serait avec std::fstream).

Boost::Iostreams a déjà un mapped_file Source, mais le problème était qu'il était mmapping ensemble de fichiers, ce qui vous limite à 2^(wordsize).Sur les machines 32 bits, 4 GO n'est pas assez grand.Il n'est pas déraisonnable de s'attendre à avoir .pack fichiers Git qui deviennent beaucoup plus que cela, j'ai donc besoin de lire le fichier en morceaux sans recourir à régulièrement des e/s de fichier.Sous les couvertures de Boost::Iostreams, J'ai mis en place une Source, qui est plus ou moins un autre point de vue de l'interaction entre std::streambuf et std::istream.Vous pouvez également essayer une approche semblable en tout juste d'hériter de std::filebuf dans un mapped_filebuf et de la même manière, l'héritage std::fstream en a mapped_fstream.C'est l'interaction entre les deux c'est difficile d'obtenir le droit. Boost::Iostreams a quelques du travail accompli pour vous, et il fournit également des crochets pour les filtres et les chaînes, j'ai donc pensé qu'il serait plus utile de mettre en œuvre cette manière.

Il y a beaucoup de bonnes réponses ici déjà que couvrir un grand nombre de points saillants, donc je vais juste ajouter un couple de questions que je ne voyais pas adressée directement au-dessus.C'est, cette réponse ne devrait pas être considérée comme exhaustive des avantages et des inconvénients, mais plutôt un addendum à d'autres réponses ici.

mmap est comme de la magie

En prenant le cas où le fichier est déjà pleinement mis en cache1 comme la ligne de base2, mmap peut sembler un peu comme la magie:

  1. mmap nécessite seulement 1 système d'appel (potentiellement) carte de l'ensemble du dossier, après qui n'a plus les appels système sont nécessaires.
  2. mmap n'a pas besoin d'une copie de la fiche de données de noyau en espace utilisateur.
  3. mmap permet d'accéder au fichier "de la mémoire", y compris le traitement avec ce que avancé trucs que vous pouvez faire à l'encontre de la mémoire, comme le compilateur auto-vectorisation, SIMD intrinsèques, le pré-chargement, optimisée en mémoire des routines d'analyse, OpenMP, etc.

Dans le cas où le fichier est déjà dans le cache, il semble impossible à battre:vous venez d'accéder directement au noyau de cache de la page, de la mémoire et il ne peut pas faire plus vite que ça.

Eh bien, il peut.

mmap n'est pas réellement de la magie, car...

mmap ne fonctionne toujours par la page de travail

Une primaire coûts cachés de la mmap vs read(2) (ce qui est vraiment comparable à niveau de l'OS syscall pour la lecture de blocs), c'est qu'avec mmap vous aurez besoin de faire "un peu de travail" pour chaque 4K page dans l'espace utilisateur, même si elle pourrait être masquée par la page de faute de mécanisme.

Pour un exemple typique de mise en œuvre qui vient de mmaps l'ensemble du dossier devra faute-dans 100 GB / 4K = 25 millions de défauts de lire un 100 GO de fichiers.Maintenant, ceux-ci seront fautes mineures, mais 25 milliards de défauts de page n'est toujours pas va être super rapide.Le coût d'un défaut mineur est probablement dans les 100s de nanos dans le meilleur des cas.

mmap s'appuie fortement sur TLB performance

Maintenant, vous pouvez passer MAP_POPULATE pour mmap pour dire la mise en place de toutes les tables de page, avant de revenir, donc il devrait y avoir pas de défauts de page alors que l'accès.Maintenant, cela a le petit problème qu'il lit aussi l'intégralité du fichier dans la RAM, qui est sur le point d'exploser si vous essayez de mapper un 100 GO de fichiers, mais c'est ignorer que, pour l'instant3.Le noyau a besoin de faire par-page de travail pour configurer ces tables de page (affiche comme noyau temps).Cela finit par être un coût important dans la mmap approche, et il est proportionnel à la taille du fichier (c'est à dire, il ne peut pas faire relativement moins important que la taille du fichier augmente)4.

Enfin, même dans l'espace utilisateur à accéder à cette cartographie n'est pas exactement libre (par rapport à de grands tampons de mémoire qui ne sont pas originaires d'un fichier de la base de mmap) - même une fois la page les tableaux sont mis en place, chaque accès à une nouvelle page va, sur le plan conceptuel, de subir une TLB miss.Depuis mmaping un fichier en utilisant le cache de la page et son 4K pages, vous pouvez à nouveau subir ce coût de 25 millions de fois pour un 100 GO de fichiers.

Maintenant, le coût réel de ces absences TLB dépend fortement de la au moins les aspects suivants de votre matériel:(a) combien de 4K TLB enties vous avez et la façon dont le reste de la traduction de la mise en cache fonctionne effectue (b) comment bien matériel prefetch traite avec le TLB - par exemple, peut prefetch déclencher une page à pied?(c) à quelle vitesse et comment parallèle la page de la marche du matériel est.Sur moderne haut de gamme x86 processeurs Intel, la page de la marche du matériel est en général très fort:il y a au moins 2 parallèle page marcheurs, une page à pied peut se produire en même temps avec la poursuite de l'exécution, et le matériel de pré-chargement peut déclencher une page à pied.De sorte que le TLB impact sur un streaming lire la charge est relativement faible et à une telle charge souvent effectuer de la même façon quelle que soit la taille de la page.Autres matériel est généralement beaucoup plus grave, cependant!

read() permet d'éviter ces écueils

L' read() syscall, qui est ce qui est généralement sous-tend le "bloc de lire" appels de type offert par exemple, en C, C++ et autres langages a pour principal inconvénient que tout le monde est bien conscient:

  • Chaque read() appel de N octets doivent copie N octets à partir du noyau vers l'espace utilisateur.

D'autre part, il évite la plupart des coûts ci - dessus, vous n'avez pas besoin de carte de 25 millions de pages de 4ko dans l'espace utilisateur.Vous pouvez généralement malloc un seul tampon mémoire tampon de petite taille dans l'espace utilisateur, et de réutiliser de façon répétée pour tous vos read les appels.Sur le noyau côté, il n'y a presque pas de problème avec les pages 4K ou TLB manque parce que toute la RAM est généralement assigné de façon linéaire à l'aide de quelques très grandes pages (par exemple, 1 GO de pages sur x86), de sorte que le sous-jacent des pages dans le cache de la page sont couverts de façon très efficace dans l'espace du noyau.

Donc, fondamentalement, vous avez la comparaison suivante pour déterminer ce qui est plus rapide pour une seule lecture d'un fichier volumineux:

Est le plus par-page de travail impliquée par le mmap approche plus coûteux que le par octet travail de copie le contenu du fichier de noyau en espace utilisateur implicite en utilisant read()?

Sur de nombreux systèmes, ils sont en fait environ équilibrée.Notez que chacune des échelles totalement différentes attributs du matériel et des OS de la pile.

En particulier, l' mmap l'approche devient relativement plus rapide lorsque:

  • L'OS est rapide mineur-la gestion des pannes et en particulier les mineurs, faute de gonflement des optimisations telles que les pannes de la autour de.
  • L'OS a une bonne MAP_POPULATE la mise en œuvre qui peut traiter efficacement de grandes cartes dans les cas où, par exemple, les pages sont contigus en mémoire physique.
  • Le matériel a fort traduction de la page de la performance, tels que la grande Tlb, rapide deuxième niveau Tlb, rapide et parallèle page-marcheurs, bonne prefetch interaction avec la traduction et ainsi de suite.

...alors que le read() l'approche devient relativement plus rapide lorsque:

  • L' read() syscall a de bonnes performances de la copie.E. g., bon copy_to_user les performances sur le noyau de côté.
  • Le noyau a une efficace (par rapport à userland) pour la carte mémoire, par exemple, à l'aide de seulement quelques grandes pages avec support matériel.
  • Le noyau a vite syscalls et une façon de garder le noyau TLB entrées autour de à travers syscalls.

Le matériel des facteurs ci-dessus varient sauvagement à travers différentes plates-formes, même au sein de la même famille (par exemple, dans les x86 générations et en particulier les segments de marché) et certainement à travers les architectures (par exemple, le BRAS vs x86 vs PPC).

Le système d'exploitation facteurs de garder en pleine mutation, avec diverses améliorations sur les deux côtés, un grand saut dans la vitesse relative pour une approche ou l'autre.Une liste récente comprend:

  • Plus de la faute-autour, décrit ci-dessus, ce qui aide vraiment les mmap cas sans MAP_POPULATE.
  • Plus de fast-path copy_to_user méthodes de arch/x86/lib/copy_user_64.S, par exemple , à l'aide de REP MOVQ lorsqu'il est rapide, ce qui aide vraiment les read() cas.

Mise à jour après le Spectre et la fusion d'

Les mesures d'atténuation pour le Spectre et la fusion des vulnérabilités considérablement augmenté le coût d'un appel système.Sur les systèmes que j'ai mesuré, le coût de "ne rien faire" appel système (qui est une estimation de la pure pour les frais généraux de l'appel système, en dehors de tout travail réel effectué par l'appel) est passé d'environ 100 ns sur un moderne système Linux à environ 700 ns.En outre, en fonction de votre système, l' page-table d'isolement fixer spécifiquement pour Débâcle peuvent avoir d'autres effets en aval, en dehors de l'influence directe du système de coût de l'appel en raison de la nécessité de recharger TLB entrées.

Tout cela est un désavantage relatif pour read() basée sur des méthodes par rapport à mmap les méthodes basées sur, depuis read() les méthodes doivent faire un appel système pour chaque "taille de la mémoire tampon" d'une valeur de données.Vous ne pouvez pas arbitrairement augmenter la taille de la mémoire tampon pour amortir ce coût, puisque l'utilisation des tampons de grande taille généralement pire depuis que vous dépassez la L1 de la taille, et sont donc constamment à la souffrance défauts de cache.

D'autre part, avec mmap, vous pouvez mapper dans une grande région de la mémoire avec MAP_POPULATE et l'accès de manière efficace, au prix d'un seul appel système.


1 Cette plus-ou-moins inclut également le cas où le fichier n'a pas été entièrement mis en cache pour commencer, mais où le système d'exploitation de lecture anticipée est assez bon pour le faire apparaître de la sorte (c'est à dire, la page est généralement mis en cache par le temps vous le voulez).C'est un petit problème, mais parce que la manière de lire-travaux à venir est souvent très différents entre mmap et read appels, et peuvent être ajustées par "informer" les appels comme décrit dans 2.

2 ...parce que si le fichier est pas mis en cache, votre comportement va être complètement dominé par IO préoccupations, y compris la façon sympathique de votre motif de l'accès est pour le matériel sous-jacent - et tous vos efforts doivent être en garantir cet accès est aussi sympathique que possible, par ex.grâce à l'utilisation de madvise ou fadvise les appels (et quel que soit le niveau d'application de changements que vous pouvez faire pour améliorer l'accès des motifs).

3 Vous pourriez obtenir autour de ce que, par exemple, de manière séquentielle mmaping dans les fenêtres de petite taille, de 100 MO.

4 En fait, il s'avère que la MAP_POPULATE l'approche est (au moins un peu de matériel/OS combinaison) est à peine plus rapide que ne l'utilisez pas, probablement parce que le noyau est l'aide de faultaround - de sorte que le nombre réel de fautes mineures est réduite par un facteur de 16 ans.

Je suis désolé, Ben Collins a perdu ses fenêtres coulissantes mmap code source.Ce serait sympa d'avoir de coup de pouce.

Oui, la cartographie du fichier est beaucoup plus rapide.Vous êtes essentiellement en utilisant l'OS de la mémoire virtuelle sous-système d'associer la mémoire à disque et vice versa.Pensez-y de cette façon:si le noyau de système d'exploitation que les développeurs pourraient le rendre plus rapide qu'ils le feraient.Parce que cela fait à peu près tout plus vite:les bases de données, le temps de démarrage, le programme de temps de chargement, et cetera.

La fenêtre coulissante approche n'est vraiment pas si difficile que plusieurs continguous pages peuvent être mappées à la fois.De sorte que la taille de l'enregistrement n'a pas d'importance tant que le plus grand de tout enregistrement unique, à tenir dans la mémoire.L'important, c'est la gestion de la comptabilité.

Si un enregistrement ne commence pas sur une getpagesize() limite, votre cartographie doit commencer à la page précédente.La longueur de la région cartographiée s'étend à partir du premier octet de l'enregistrement (arrondi vers le bas, si nécessaire, au plus proche multiple de getpagesize()) pour le dernier octet de l'enregistrement (arrondi au multiple le plus proche de getpagesize()).Lorsque vous avez terminé le traitement d'un dossier, vous pouvez annuler le mappage (), et de passer à la suivante.

Tout cela fonctionne très bien sous Windows à l'aide de CreateFileMapping() et MapViewOfFile() (et GetSystemInfo() pour obtenir SYSTEM_INFO.dwAllocationGranularity --- pas SYSTEM_INFO.dwPageSize).

mmap devrait être plus rapide, mais je ne sais pas combien.Cela dépend beaucoup de votre code.Si vous utiliser mmap, il est préférable de mmap l'ensemble du dossier à la fois, qui va vous rendre la vie beaucoup plus facile.Un problème potentiel est que si votre fichier est plus gros que 4 go (ou, dans la pratique, la limite est plus faible, souvent de 2 go), vous aurez besoin d'une architecture 64 bits.Ainsi, si vous utilisez un 32 de l'environnement, vous ne voulez probablement pas à l'utiliser.

Cela dit, il y a peut être une meilleure voie pour l'amélioration des performances.Vous avez dit le fichier d'entrée sera scannée de nombreuses fois, si vous pouvez le lire en une seule passe, et ensuite être fait avec elle, qui pourrait être beaucoup plus rapide.

Je suis d'accord que mmap avais fichier I/O sera plus rapide, mais si votre banc de la code, ne pas le contre-exemple être un peu optimisé?

Ben Collins a écrit:

char data[0x1000];
std::ifstream in("file.bin");

while (in)
{
    in.read(data, 0x1000);
    // do something with data 
}

Je suggère aussi d'essayer:

char data[0x1000];
std::ifstream iifle( "file.bin");
std::istream  in( ifile.rdbuf() );

while( in )
{
    in.read( data, 0x1000);
    // do something with data
}

Et au-delà, vous pouvez également essayer de faire la taille de la mémoire tampon de la même taille qu'une page de mémoire virtuelle, dans le cas 0x1000 n'est pas la taille d'une page de mémoire virtuelle sur votre machine...À mon humble avis mmap avais fichier I/O gagne encore, mais cela devrait rendre les choses de plus près.

Peut-être que vous devez pré-traiter les fichiers, afin que chaque enregistrement est dans un fichier séparé (ou au moins que chaque fichier est un mmap-mesure de la taille).

Aussi pourriez-vous faire à toutes les étapes de traitement pour chaque enregistrement, avant de passer à la suivante?Peut-être, qui permettrait d'éviter certains des IO dessus?

À mon avis, à l'aide de mmap() "juste" déchargerait le développeur d'avoir à écrire leur propre code de mise en cache.En un simple "lire au travers de fichier eactly une fois" le cas, cela ne va pas être dur (bien que, comme mlbrock souligne-vous toujours enregistrer la copie de la mémoire dans l'espace de processus), mais si vous êtes va-et-vient dans le fichier ou sauter bits et ainsi de suite, je crois que les développeurs du noyau ont probablement faire un meilleur travail de mise en œuvre la mise en cache que je peux...

Je me souviens de la cartographie d'un énorme fichier contenant une structure en arbre en mémoire il y a des années.J'ai été étonné par la vitesse par rapport à la normale de la sérialisation qui implique beaucoup de travail dans la mémoire, comme l'allocation de nœuds de l'arborescence et de réglage des pointeurs.Donc, en fait, j'étais en comparant un seul appel à mmap (ou son homologue sur Windows) contre beaucoup (BEAUCOUP) appels à l'opérateur new et constructeur appelle.Pour ce genre de tâche, mmap est imbattable par rapport à la dé-sérialisation.Bien sûr, on doit examiner les boosts amovibles pointeur pour cela.

Cela sonne comme une bonne de cas d'utilisation pour le multi-threading...Je pense que vous pourrait assez facilement la configuration d'un thread à la lecture des données, tandis que l'autre(s) processus.Que peut être un moyen d'augmenter considérablement la performance perçue.Juste une pensée.

Je pense que la meilleure chose à propos de mmap est possible asynchrone lecture avec:

    addr1 = NULL;
    while( size_left > 0 ) {
        r = min(MMAP_SIZE, size_left);
        addr2 = mmap(NULL, r,
            PROT_READ, MAP_FLAGS,
            0, pos);
        if (addr1 != NULL)
        {
            /* process mmap from prev cycle */
            feed_data(ctx, addr1, MMAP_SIZE);
            munmap(addr1, MMAP_SIZE);
        }
        addr1 = addr2;
        size_left -= r;
        pos += r;
    }
    feed_data(ctx, addr1, r);
    munmap(addr1, r);

Le problème est que je ne peux pas trouver la bonne MAP_FLAGS de donner un indice que cette mémoire devrait être synchronisés à partir d'un fichier le plus vite possible.J'espère que MAP_POPULATE donne le droit de l'indice de mmap (c'est à direil ne va pas essayer de charger tout le contenu avant de retour d'appel, mais qu'en asynchrone.avec feed_data).Au moins il donne de meilleurs résultats avec ce drapeau même que manuel précise qu'il ne fait rien sans MAP_PRIVATE depuis 2.6.23.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top