Léa-Linux & amis :   LinuxFR   GCU-Squad   GNU
optmiser temps de lecture / ecriture
Envoyé par: mig73

Bonjour,
je travail sur un système embaqué, dont l'OS est Linux (+RTAI).
Les contraintes de temps sont relativement fortes: cette carte recoit des trames depuis son controleur CAN. Nous voudrions stocker les trames recues dans un fichier de log.

Principe de fonctionnement:
Des drivers rtai bas niveau, recupère les trames acquises et les insèrent dans une fifo RTAI (passerelle entre RTAI et le Userspace).
Il nous faut alors developpé un programme utilisateur qui recupèrent les trames depuis la fifo soft rtai et les ecrive dans un fichier de log (txt par exemple).
La carte root par NFS, cad que son système de fichier est physiquement présent sur un PC hote. Ainsi, du point de vue de la carte, il nous suffit d'ecrire dans un fichier texte, sans avoir de contraintes d'espace mémoire.

Les contraintes ici sont en terme de temps:
Une trame est acquise toutes les 90us, ce qui signifie que toutes les phases pour l'extraire du controleur, la transmettre a l'espace utilisateur, puis l'ecrire dans un fichier doit être inférieure à 90us.
Actuellement:
le pre-traitement d'1 trame recue prend 6-7us
acquisition trame depuis controleur hard 10 us
passage vers userspace (ecriture dans fifo soft rtai) 18us

Il reste donc environ 55 us / 90us pour lire une trame dans la fifo soft rtai et l'ecrire dans un fichier texte (via NFS...)

J'utilise la fonction C read pour extraire une trame de la fifo rtai.
et write pour ecrire dans un fichier texte.

Le temps moyen total est 250us (lecture + ecriture) !


Est il possible d'optimiser ce temps ?

Dans notre cas, la quantité de donées a transférer est fiable (1 trame = 1 20aine d'octets). Il semble donc que ce soit les temps d'accès qui aient leur importance et non les temps de transfert eux-même.

Pourquoi la lecture dans une fifo rtai est elle (relativement) si longue (env 100us)?

Pour l'ecriture dans le fichier de log, j'imagine que les différentes couches de communication a traverser doivent ralentir cette fonction. Est il possible de donner une priorité au PC hote pour l'ecriture depuis la carte?

Peut être faut il utiliser des sockets ou autres moyens de communication?


Bref, la moindre idée, que ce soit dans le code, les fonctions utiles, les moyens de communication, l'optimisation des appels systèmes etc, me serait d'une aide précieuse.

Merci

Poste le Tuesday 25 July 2006 11:49:44
Répondre     Citer    
Re: optmiser temps de lecture / ecriture
Envoyé par: e_gaillard37

bonjour,
si je comprends bien tu veux ecrire 10 000 fois par seconde 20 octets
200 ko * 86 400
soit 17 giga par jour
Dons tu remplis une machine en moins d'un mois
J'imagine donc que ton traiement est un truc d'acquisition de donnees sur un temps relativement court
QQ seconde a qq heures.
Disons 1 heure... c moins d'un giga

Je pense que lire et ecrire un fichier est une notion lourde, qui peut en cas de swap prendre des milliers de us
C'est un non sens

Si une machine lit ton flux a travers le fichier que tu constitue c la catastrophe assuree

si tu traites moins d'un GO d'un coup ...
Mets de la memoire ( ou pas )
et remplit un tableau en memoire

Maintenant 2 choses ... tu transferts de l'information au fil de l'eau pour un autre process ou tu stockes et c traite apres apparament c la 2 eme solution

Si tu transfert en flux a une machine qui lit ton fichier c'est un non sens car tu tombes sur le pb de lecture de fichier car la machine qui lit en fin a le mem pb


Si tu stockes un paquet d'info plus petit que la memoire dont tu disposes, mets en memoire... Ecrit ton fichier a la fin


Un traitement de masse comme le tien en flux ne peut pas passer par une notion de fichier

Mais si tu travailles en memoire , en flux... fais un buffer avec rotation
et le programme qui recoit l'info (si il existe) devra accepter le meme type de buffer en memoire partagee.
Partager memoire entre programme c possible... Y'a qu' demander
Si comme je le pense tu ecris 20 octects ds un fichier pour qu'un autre prog lise la meme chose ...A cette vitesse c perdu d'avance

Enfin , si tu ecris 200 ko dans un tableau par sec ... Tu peux peut etre ecrire des paquets ds un fichier au fur et a mesure. Mais la le prog qui ecrit en memoire et celui qui lit ne peut pas etre le meme ... Tu remplis 1 m ... L'autre attends...Tu remplis un second m le second progr ecrit le premier sur le disque.Et reoutr au premier... D'ou la notion de memoire partagee

Mais pour moi bosser en memoire c plus simple...On ecrit a la fin

Cela dit j'ai peut etre pas tout compris

Bye

Poste le Thursday 3 August 2006 20:53:51
Répondre     Citer    
JE complete
Envoyé par: e_gaillard37

J'ai relu ton speech,

desole... Si tu as la contrainte du fread dans un buffer memoire et que celui ci est lent... La je sais pas si on peut optimiser
Et c pas terrible... car cela peut signigier que ta carte peut exceder la vitesse de ton pseudo fread... auquel cas... c mort tu depasses ta capacite machine
Mais peut etre ta carte a un autre mode de transfert... Un truc memoire avec la notion de drapeau


Enfin si tu as peur d'outrepasser ta capa memoire avec tes donnees...
Un buffer memoire s'impose avec rotation. Un pc peut sans pb ecrire 200 ko par sec qd meme ... mais pas forcement en 10000 fois

Bref ton pb est pas facile...

Enfin... tes donnees de 20 octets changent elles a chaque enreg ??? Y'a t il une notion d'instant a l'interieur ?

Si tu as trouve et que tu as choisi une solution, exprime toi ici. Je suis curieux de ce genre de choses

Bye


Poste le Friday 4 August 2006 18:44:41
Répondre     Citer    
Re: JE complete
Envoyé par: mig73

Bonjour,
tu as bien compris mon casse tête en effet.
Il s'agit bien, globalement d'écrire 10000 trames de 20 octets chaque seconde.
Effectivement, cela représente une quantité astronomique si l'application tournait en permanence.
Dans notre cas, il s'agit de réaliser un enregistreur de bord automobile, qui se déclenche que sur certains évenement (apparition d'un trame dont le champ N prend une valeur M par ex, etc...) ce qui signifie que la carte va stocker temporairement les trames recues, les traiter (étudier si elle correspondent à un evenement declenchant l'enregistrement ou non).
Dans le cas où elles ne correspondent pas, etant donné qu'on ne peut acquérir en permanence faute de mémoire infinie, effectivement nous devons utiliser un méthode basée sur les buffers tournants. Ici la fifo joue ce double role, a la fois de passerelle entre les différents espaces (kernel / user) et de tampon.

Donc pour ce qui est de l'aspet mémoire, on peut l'omettre quelque peu, puisque si l'enregistreur de bord stock pendant 1 heure après l'evenement declencheur, on pourra considérer qu'il y a assez d'information pour effectuer les diagnostic necessaires, et deceler d'eventuels erreurs.

La où se situe le problème est bel et bien le temps de traitement.
D'apres toi, la solution la plus simple est d'acquérir une quantité de trames, puis d'effectuer l'ecriture dans un fichier distant seulement une fois l'acquisition terminée. Jsuis parfaitement daccord avec toi, ce principe etait utilisé sur le precedent enregistreur: un buffer circulaire acquérissait les trames, le CPU les traitait, et sur detection d'un evenement declencheur, enregistrait sur la carte une certaine quantité de trames dans la limite de la mémoire disponible. Puis, une fois l'enregistrement terminé, on ecrivait les trames acquises dans un fichier sur un PC distant, destinées a etre traiter posterieurement.

Aujourdhui on beneficie d'une nouvelle plateforme, beaucoup plus performante que la précedente, car elle nous permet d'acquérir sans perte, des trames toutes les 90us. On souhaite realiser un proto capable de realiser cette acquisition. Mes supérieurs, trop ambiteux au début, pensaient même pouvoir realiser un traitement sur ces trames (traitement assez complexe realisé par le PC distant dans la version precedente)
Apres m'etre apercue des problèmes auxquels nous sommes confrontés, nous avons revu les objectifs à la baisse. C'est pourquoi, on souhaite, une simple acquisition à la volée des trames et leur enregistrement sur PC distant (le PC proposant un espace de stockage bien plus important, et effectuerait les différents traitements postérieurs)


Voila pourquoi je "chasse" la microseconde à tout va.
J'ai par ailleurs essayer d'utiliser les sockets en TCP pour maitriser l'acces en ecriture par Ethernet sur le PC distant. J'ai gagner encore quelques us mais encore pas assez.

Il semblerait qu'en UDP je puisse en gagner encore plus, mais utiliser l'UDP serait un non sense, car il ne garantit pas la non perte des trames, et leur ordre de reception.

J'essaie donc de chercher où se situe le goulot d'etrenglement en quelques sortes.


Tu me confortes egalement dans mon idée d'utiliser la mémoire partagée. Le seul point noir est qu'on tire profit de la mémoire partagée lorsqu'elle est effectivement partagée par deux plateformes ou CPU différents.
Ainsi, grossièrement, comme tu l'as expliqué, quand le premier fait l'acquisition, le second accede a un espace different, et ecrit une trame precedement acquise et rebelotte. On aurait donc un reel parallelisme, et moyennant une synchronisation des deux CPU, on gagnerait reellement en temps. Comme tu l'as dis, il est difficile de faire faire la même chose au même micro, etant donné les contraintes de temps.

Dans mon cas, le buffer mémoire etant en embarqué sur la carte, c'est le même CPU qui realise l'acquisition et l'ecriture. Certes, il semblerait que l'acces en ecriture/lecture à la mémoire partagée sous Linux RTAI est plus performant que l'acces au FIFO ou mailboxes (ca reste a vérifier) mais ce qui est sur, c'est qu'on perd l'interet de la mémoire partagée, puisqu'on est en pseudo parallèlisme.

La mémoire partagée semble être la solution, mais je ne sais pas comment la partager vers le PC distant.
De plus, la où l'on soulage le CPU embarqué, car il n'effectue qu'une seul opération grossièrement, on risque peut etre de perdre, ou du moins de ne pas gagner autant que ce qu'on pensait, puisque tout le mecanisme de synchronisation, c'est à dire qui appel le PC distant pour lui dire qu'il a accède a telle partie de la mémoire, et cela a travers une communication Ethernet, peut prendre un certains temps. A prendre en compte...

Si quelqu'un connait les mecanismes pour partager une mémoire circulaire embarquée sur une carte entre le CPU de la carte (OS Linux RTAI) et un PC distant (Linux NON RTAI) ?
il semble que je ne pourrai pas utiliser les "rtai_scb" (Shared (memory) Circular buffer) car le PC distant n'est pas temps réel. Néanmoins une mémoire partagée même non temps réelle devrait permettre un gain de temps important.

Si quelq'un a un avis / conseil / critique sur le sujet, j'apprécierai votre participation.

Merci d'avance

Poste le Wednesday 16 August 2006 12:02:02
Répondre     Citer    
Re: Help
Envoyé par: LinuxMen

Bonjour à tous,

je suis nouveau dans les systemes embarqués.
je travail sur un système embaqué, dont l'OS est Linux (+RTAI 3.4 CV).mon une carte ethernet, je veux tester les temps de lecture/ecriture de donnée entre les deux cartes ( je veux determiner l'efficacité de RTAI). et je ne sais pa par ou commencer , dois-je utiliser fifo comme moyen de communication entre la carte et l'OS, si quelqu'un peu m'aider par un bou de code ou par des exemple je serai ravi,

Merci d'avance

Poste le Friday 23 March 2007 10:37:01
Répondre     Citer    
Re: optmiser temps de lecture / ecriture
Envoyé par: Sve@r

Citation
mig73
J'utilise la fonction C read pour extraire une
trame de la fifo rtai.
et write pour ecrire dans un fichier texte.

Le temps moyen total est 250us (lecture +
ecriture) !


Est il possible d'optimiser ce temps ?
La fonction "read" est bas niveau. Si tu lui demandes 1 octet, elle va activer le disque pour 1 octet. En jouant sur la taille de ton buffer de lecture (lire par exemple 100 trames d'un coup) tu peux gagner en perfs...


L'homme qui murmurait à l'oreille des pingouins
[fr.lang.free.fr]

Poste le Wednesday 28 March 2007 11:16:35
Répondre     Citer    

Veuillez vous authentifier auparavant pour commenter.

 

Ce forum !
optmiser temps de lecture / ecriture
Pour poser vos questions sur les scripts shell, le Perl, le C, etc... Attention : nous ne sommes pas des spécialistes du dev, ce forum est juste pour de petites aides ponctuelles concernant le développement et les outils de développement.

Sauf mention contraire, les documentations publiées sont sous licence Creative-Commons