Bonjour,
Je travaille sur un logiciel qui va devoir copier des données de la mémoire vers le disque dur. Mettons des blocks de 200 Mega-octets.
Je me dis: mmm, je devrais utiliser un mécanisme de Direct Memory Access (DMA). Mais je n'ai aucune idées. Une recherche sur internet me donne surtout des posts traitant de problèmes de lenteurs de disque-dur, mais pas trop sur la manière de coder ça.
J'imagine que c'est un controlleur DMA qui s'occupe de ça. Comment lui "parler" pour lui faire envoyer des choses vers le disque ?
Merci!
# Euh ...
Posté par Ph Husson (site web personnel) . Évalué à 6.
Mais tu peux utiliser mmap(2), c'est beaucoup plus simple et je doute que niveau perf ce soit radicalement différent, et accessoirement t'as pas à gérer toi meme le systeme de fichier.
# File mapping
Posté par Obsidian . Évalué à 3.
Ensuite, tu peux faire du raw device. Avant, ça se fait en associant un /dev/raw/rawX à ton périphérique. Maintenant, c'est en passant l'option O_DIRECT à open().
Par contre, d'après ce que je lis, il semblerait que ce qu'il te faille, c'est du file mapping. Vois du coté de $ man mmap. C'est un appel système, donc en C, aisément encastrable dans du code en C++.
Bon courage.
[^] # Re: File mapping
Posté par fabricius . Évalué à 1.
Je ne sais pas trop si ce que je dois faire c'est du file mapping ou autre. En fait je fais cela:
Je reçois des paquets UDP, je prend le payload et je rajoute un timstamp (l'heure) et l'adresse IP/port d'origine.
Je stocke le tout en mémoire, et quand j'en ai suffisamment, je l'envois vers le disque.
Le tout dans un thread, et il y a plusieurs threads qui font la même chose, avec bien sur un mecanisme pour qu'un seul thread a la fois ecrive sur le disque.
[^] # Re: File mapping
Posté par fabricius . Évalué à 1.
http://en.wikipedia.org/wiki/Mmap
http://en.wikipedia.org/wiki/Raw_device
Je pense aussi que je suis plus proche du file mapping (mmap) que du raw device...
[^] # Re: File mapping
Posté par Obsidian . Évalué à 2.
Après, si tu reçois des milliers de paquets à la seconde, tu peux peut-être envisager autre chose.
[^] # Re: File mapping
Posté par fabricius . Évalué à 1.
Je precise que ce sera une machine de guerre, comme PC. Un truc super puissant.
[^] # Re: File mapping
Posté par jigso . Évalué à 2.
[^] # Re: File mapping
Posté par fabricius . Évalué à 1.
Ta solution de passer par un autre thread intermediaire qui pourrait faire tampon est une bonne idée! Un peu comme un graveur de CD.
[^] # Re: File mapping
Posté par jigso . Évalué à 2.
[^] # Re: File mapping
Posté par Obsidian . Évalué à 2.
Étant donné que les machines récentes sont toutes hyper-threadées, je ferais exactement deux processus, qui partagent un buffer circulaire (le fameux graveur de CD). L'une en charge du disque, qui peut se permettre de l'attendre, et l'autre qui remplit le tampon.
Par contre, je pense quand même que la charge sera moins lourde si un seul processus lit tous les ports. Il y a un seul noyau et surtout, c'est la même carte réseau derrière pour tout le monde.
[^] # Re: File mapping
Posté par Obsidian . Évalué à 1.
J'ajoute que si tu en es là, et que l'opération à faire sur les paquets est fort simple, largue le C++ et code directement en C. Tu économiseras beaucoup de ressources.
[^] # Re: File mapping
Posté par fabricius . Évalué à 1.
Je fais des essais avec la librairie GNU Common C++, et je n'arrive même pas a compiler les fichiers exemples...
Mais bon, je suis au boulot, et je n'ai pas trop le choix.
[^] # Re: File mapping
Posté par guppy . Évalué à 1.
Pas de raison qu'un code aussi simple soit plus lent en C++ qu'en C.
C'est l'architecture du programme qui va déterminer son efficience.
Ici, en C ou en C++, c'est l'algorithme qui va jouer ...
De toute manière, je ne pense pas que tu t'y prennes correctement. Fais déjà un soft qui fonctionne avant de passer à son optimisation, pas l'inverse.
Par contre, pour l'architecture, évite d'utiliser du polymorphisme dynamique, car c'est d'ici que viendrait une éventuelle baisse de perf par rapport à un code en C. Mais de toute manière le sujet ne s'y prête peu.
[^] # Re: File mapping
Posté par Laurent Morel . Évalué à 2.
L'utilisation de open(O_DIRECT) a de multiples contraintes, mais pourrait être envisageable (à voir, économise une copie mémoire...).
Pour "flusher" un fichier ouvert avec fopen(), c'est plutôt fflush() que sync. flush() envoie les données de l'espace utilisateur vers le noyau.
"sync" n'est pas flush : sync écrit les données encore en RAM sur le support physique, pour TOUS les systèmes de fichiers : c'est très lourd (il existe fsync() pour faire cela par fichier). En l'occurrence, je ne sais pas si c'est ce que cherche à faire fabricius ?
Deux threads suffisent : un premier qui fait select() ou epoll() sur les sockets + remplit la ram, et un second qui vide la ram sur le disque (modèle classique producteur / consommateur).
Sauf architecture SMP, je ne pense pas que davantage de threads permettent de gagner en performance...
[^] # Re: File mapping
Posté par fabricius . Évalué à 1.
Pour les 2 threads, effectivement, ca devrait suffire. Et ça evitera les changement de contexte, donc on devrait gagner en performance.
[^] # Re: File mapping
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
Utilises des gros write (genre >> 1 Mo). Si tu maitrises ton systeme de fichier privilegies, utilises des gros cluster, ils sont plus rapide que les petits si tu as des gros fichiers.
Logiquement, il sera plus rapide d'ouvrir une seul fichier que plusieurs, la tête du disque n'aura pas a bouger.
Oublies mmap() qui ne permet pas de faire grossir un fichier.
Fais gaffe que fseek utilise un entier 32 bits, cela peut poser des ennuis sur un fichier de plus de 2 Go.
Le top des perfs devrait etre obtenu avec un thread lecteur qui utilise select() ou un equivalent (poll ?) et un thread d'ecriture.
"La première sécurité est la liberté"
[^] # Re: File mapping
Posté par fabricius . Évalué à 1.
Effectivement, je maitrise mon systeme de fichier: c'est quelqu'un de mon equipe qui va s'occuper de l'installation de la distrib, une debian. Je vais lui demander d'adapter la taille des clusters pour que ça soit plus adapté aux gros fichiers.
[^] # Re: File mapping
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
"La première sécurité est la liberté"
[^] # Re: File mapping
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
Mais mmap se comporte toujours mal, si le fichier devient plus gros que la RAM par exemple.
"La première sécurité est la liberté"
[^] # Re: File mapping
Posté par guppy . Évalué à 1.
Logiquement, il sera plus rapide d'ouvrir une seul fichier que plusieurs, la tête du disque n'aura pas a bouger.
C'est pas faux, mais la fragmentation peut réduire le bénéfice à 0. Difficile à "prédire" dans plus de précisions.
# splice ?
Posté par galactikboulay . Évalué à 1.
Je me demande si ce genre de cas ne pourrait pas profiter de l'appel système "splice" qui permet de balancer des données d'un file descriptor (dans ton cas, ça serait ton socket) vers un autre file descriptor (le fichier sur disque), sans avoir besoin de recopier des données entre userland et kernel.
http://en.wikipedia.org/wiki/Splice_(system_call)
J'avoue que je n'ai jamais utilisé, et ça ne marche que si tu veux recopier de la donnée "brute".
[^] # Re: splice ?
Posté par fabricius . Évalué à 1.
[^] # Re: splice ?
Posté par Nicolas Boulay (site web personnel) . Évalué à 2.
Si tu as 2 systèmes de fichiers (2 disques, 2 controleurs), un pour les donnes et un pour l'index, cela permet de gagner en perf brut.
"La première sécurité est la liberté"
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.