2010-04-03 5 views
2

Je veux copier un grand fichier basé sur un ram (situé dans/dev/shm direcotry) sur un disque local, est-il possible d'obtenir une copie efficace au lieu de lire un caractère par un ou créer un autre morceau de mémoire? Je ne peux utiliser que le langage C ici. Y at-il de toute façon que je peux mettre le fichier de mémoire directement sur le disque? Merci!Comment copier efficacement un fichier ram_base sur le disque

+0

Vous obtiendrez des performances beaucoup plus élevées si vous utilisez des blocs plus grands que juste un octet. La solution optimale serait de laisser le matériel le faire en utilisant DMA, mais malheureusement je ne sais pas si cela peut être fait sur Linue. – Tronic

Répondre

0

/dev/shm est de la mémoire partagée, donc une façon de la copier serait de l'ouvrir en tant que mémoire partagée, mais franchement je ne pense pas que vous allez gagner quelque chose. Lors de l'écriture de votre fichier de mémoire sur le disque, le goulot d'étranglement sera le disque. Assurez-vous simplement d'écrire des données en gros morceaux, et ça devrait aller.

0

Vous pouvez simplement copier comme tout autre fichier:

cp /dev/shm/tmp ~/tmp 

Ainsi, un moyen rapide, simple consiste à émettre une commande cp via system().

+0

-1 parce qu'il s'agit d'une solution peu performante et qu'elle utilise un programme externe (ce qui provoque divers problèmes en soi) via system() (qui exécute la commande en utilisant un shell, provoquant divers autres problèmes).L'implémentation d'une opération de copie identique en C ne nécessite que quelques lignes de code. – Tronic

+0

D'accord avec Tronic. –

+0

@Tronic - Assez juste; soin de poster du code? –

2

Je voudrais mmap() les fichiers et faire memcpy() entre eux.

+0

Je doute que cela offre de bonnes performances non plus. Il fait toujours la copie sur le CPU, et dans les benchmarks MMAP a tendance à être plus lent pour l'accès linéaire que d'autres méthodes. – Tronic

+1

Ceci ne force pas le processeur à toucher la mémoire. Si les données sont déjà définies et doivent juste être écrites, je pense que c'est une manière très directe d'accomplir la tâche. – Potatoswatter

+0

'memcpy()' impliquera certainement le processeur touchant la mémoire. Il n'a aucune idée que la destination est un fichier mappé en mémoire. – caf

0

Vous pouvez essayer de voir si l'appel système splice fonctionne pour cela. Je ne suis pas sûr que ce soit le cas, car il a quelques restrictions sur les types de fichiers avec lesquels il peut travailler, mais si cela fonctionne, vous l'appellerez plusieurs fois avec des demandes de taille de page mémoire (ou plusieurs pages multiples) jusqu'à la fin , et le noyau le manipulerait très efficacement.

Si cela ne fonctionne pas, vous devrez effectuer mmap ou faire du vieux read/write. La lecture et l'écriture dans des blocs de la taille d'une page mémoire rendent les choses beaucoup plus efficaces. Cela peut être encore plus efficace si vos tampons sont alignés sur la taille de la mémoire car cela ouvre la possibilité au noyau de simplement déplacer les données vers/depuis la mémoire de votre processus via la gestion de la mémoire plutôt que de copier les données.

0

La seule chose que vous pouvez faire est read() dans les blocs alignés en taille de page. Je suppose que vous devez garantir les données telles qu'elles sont écrites, ce qui signifie que vous devez ignorer les tampons via posix_fadvise() ou utiliser O_DIRECT (j'utilise généralement posix_fadvise(), mais O_DIRECT est approprié ici).

Dans ce cas, la vitesse d'écriture du support seul détermine la vitesse à laquelle cela se produira.

Si vous n'avez pas besoin de contourner les tampons, l'opération se terminera plus rapidement, mais il n'y a aucune garantie que les données seront réellement écrites en cas de redémarrage/panne de courant/etc. Puisque la source des données est En mémoire partagée, je devine (encore une fois) que vous voulez que l'écriture soit garantie. La seule chose que vous pouvez optimiser est combien de temps il faut à read() pour obtenir des données de la mémoire partagée dans votre propre espace d'adressage, quels morceaux alignés de taille de page vont s'améliorer.

1

Merci les gars pour l'aide! Je l'ai fait en mmap le fichier RAM et écris le bloc entier directement à la destination. memcopy n'a pas été utilisé car j'écris actuellement dans un système de fichiers parallèle (pvfs), qui ne supporte pas l'opération mmap.

Questions connexes