Bonjour,
j'ai un programme qui enregistre sur le disque dur des images en provenances de plusieurs caméras. Il tourne en roue libre, le plus vite possible.
L'enregistrement se fait via la bibliothèque gdk-pixbuf. Je fais un appel à gdk_pixbuf_save, qui enregistre l'image dans le format que j'ai choisi. J'ai accès au code de gestion de ce format graphique (je l'ai écrit), et l'écriture des données se fait via un unique fwrite (mais sans fflush ensuite, mais il est normalement fait automatiquement quand le fichier est fermé juste après).
Problème : souvent, je n'ai plus d'enregistrement pendant près de 0,2 à 0,8 secondes, tandis que d'autres fois je tourne à 29 images/secondes. Le pire c'est que le comportement n'est assez différent d'une exécution à l'autre. Exemple avec ces graphiques représentant en abcisse le numéro d'image et en ordonnée le temps d'enregistrement de l'image en question.
image_perdue
image_perdue
image_perdue
image_perdue
image_perdue
J'ai d'abord pensé à une lenteur du disque dur, mais en enregistrant sur un ramdisk, même problème. Je n'ai aucun autre processus qui consommerait beaucoup de CPU et pourrait ralentir le bestiau. J'ai tenté d'augmenter la priorité coté processus et E/S avec nice et ionice, sans succès. Et puis En utilisant strace, j'ai pu me rendre compte que mon fwrite est traduit en deux appels à write, et que le "décrochage" survient toujours au même endroit : entre ces deux write.
Tout ça s'exécute sur une Fedora Core 6 (base de RHEL 5).
Quelqu'un aurait une idée d'où ça peut venir ? Un cache quelconque qui coince ?
Je suis preneur de toute piste…
# Mauvais OS
Posté par liberforce (site web personnel) . Évalué à 2.
[^] # Re: Mauvais OS
Posté par liberforce (site web personnel) . Évalué à 2.
[^] # Re: Mauvais OS
Posté par liberforce (site web personnel) . Évalué à 2.
[^] # Re: Mauvais OS
Posté par liberforce (site web personnel) . Évalué à 2.
# Faut faire du Realtime!
Posté par Christophe --- . Évalué à 3.
à mon avis, ce qui se passe c'est que de temps en temps le système de fichier à besoin de faire quelques opérations, par exemple réorganiser la liste des fichiers, ou alors il y a un autre programme qui accède au disque, qui font que tes requêtes sont mises en attentes.
Personnellement, je verrais deux solution:
- il y a beaucoup de gens qui ont déjà réfléchi à ce genre de problèmes, de la est apparu la notion de "temps réel" (real-time). La bonne solution consiste donc à utiliser un noyau avec les patchs qui vont bien (je ne suis plus au courant de l'actualité de ce côté là) et d'utiliser l'API correspondante dans ton programme.
- l'autre solution consiste à repenser ton programme. Tu sait que le système ne va pas te garantir les temps de sauvegarde, il faut donc séparer en deux:
* un process ou thread qui va récupérer les images au fur et à mesure;
* un autre, qui prend en charge la sauvegarde au fur et à mesure.
Attention à la communication entre les deux si tu ne veux pas voir réapparaître de limite!
Bon courage,
Christophe.
[^] # Re: Faut faire du Realtime!
Posté par liberforce (site web personnel) . Évalué à 3.
Heureusement c'est un mode non-nominal de mon programme, normalement j'analyse les images à la volée sans les stocker. Alors je pense que je vais stocker les images dans une file d'attente et les écrire en fin de capture, afin de ne pas ralentir cette dernière.
Merci pour tes conseils.
[^] # Re: Faut faire du Realtime!
Posté par neologix . Évalué à 2.
Oui.
Le noyau Linux vanilla n'est pas temps réel.
Tu pourrais essayer avec d'autres ordonnanceurs d'E/S.
Je suppose que RHEL utilise CFQ par défaut, tu peux essayer avec deadline.
[^] # Re: Faut faire du Realtime!
Posté par GeneralZod . Évalué à 4.
Même si un noyau patché PREEMPT-RT n'est pas un noyau temps-réel à strictement parler (on parle plutôt de qualité de service), même fortement stressé, on arrive à des latences max de moins de 10 ms. L'avantage par rapport à un vrai noyau temps-réel comme Xenomai, c'est que c'est assez simple à mettre en oeuvre, et ça demande peu de modifications pour un bon programme.
http://rt.wiki.kernel.org/index.php/HOWTO:_Build_an_RT-appli(...)
Pour optimiser les I/O, quelques pistes :
* écriture vectorisé (writev) : ça permet au noyau d'optimiser les I/O, les opérations sont atomiques, en général ça pulse bien. C'est une technique souvent utilisée dans la vision industrielle.
* écriture asynchrone (man aio.h) : ça revient plus ou moins à l'idée de Christophe d'une gestion concurrente des écritures sans l'overhead lié à la gestion des threads. Un excellent article sur la question :
http://www.ibm.com/developerworks/linux/library/l-async/?ca=(...)
# cache disque ?
Posté par Pascal Terjan (site web personnel) . Évalué à 1.
[^] # Re: cache disque ?
Posté par liberforce (site web personnel) . Évalué à 2.
Suivre le flux des commentaires
Note : les commentaires appartiennent à celles et ceux qui les ont postés. Nous n’en sommes pas responsables.