2008-10-10 7 views
5

J'écris une petite application qui écrit des images jpeg à vitesse constante sur une carte SD. Je choisis un système de fichiers EXT3, mais le même comportement a été observé avec un système de fichiers EXT2.Performance d'écriture sur carte SD

Ma boucle d'écriture ressemble à ceci:

get_image() 
fwrite() 
fsync() 

Ou comme ceci:

get_image() 
fopen() 
fwrite() 
fsync() 
fclose() 

J'affiche également des statistiques de synchronisation, et je peux voir mon programme est parfois bloqué pendant plusieurs secondes. Le taux moyen est toujours bon, car si je garde les images entrantes dans un fifo, alors je vais écrire beaucoup d'images dans un court laps de temps après un tel décrochage. Savez-vous si c'est un problème avec le système d'exploitation ou s'il est lié à la carte SD elle-même? Comment pourrais-je me rapprocher du temps réel? Je n'ai pas besoin de temps fort, mais être bloqué pendant plusieurs secondes n'est pas acceptable.

Une certaine précision: Oui, il est nécessaire de fsync après chaque fichier, car je veux que l'image soit sur le disque, pas dans un tampon utilisateur ou kernel. Sans fsyncing, j'ai un meilleur rendement, mais toujours un décrochage inacceptable. Je ne pense pas que ce soit un problème de tampon, puisque le premier décrochage se produit après que 50 Mo ont été écrits. Et selon la page de manuel, fsync est ici précisément pour s'assurer qu'il n'y a pas de données tamponnées.

Précision concernant le taux d'écriture moyen: J'écris à un taux qui est durable avec la carte que j'utilise. Si j'empile l'image entrante en attendant la fin d'un fsync, après ce décrochage, le taux de transfert d'écriture augmentera et je reviendrai rapidement au taux moyen. Le taux de transfert moyen est d'environ 1,4 Mo/s.

Le systeme est un ordinateur portable moderne en cours d'exécution ubuntu 8.04 avec un stock Kee (2.6.24.19)

Répondre

1

Je ne suis pas très bien informé dans ce domaine, mais les symptômes que vous décrivez sonne beaucoup comme remplissant un tampon. Il se peut que vous remplissiez un tampon dans l'enregistreur de fichiers ou dans le périphérique d'E/S communiquant avec la carte SD elle-même. Vous devez alors attendre jusqu'à ce qu'il écrit réellement les données sur la carte (vidant ainsi le tampon) avant que vous puissiez écrire plus. Les cartes SD ne sont pas particulièrement rapides. Si vous pouvez trouver un moyen de vérifier si les données sont réellement écrites sur la carte pendant ces pauses, cela vérifierait ma théorie. Certains lecteurs de cartes ont une LED qui clignote lors de l'accès aux données - ce serait probablement un bon indicateur.

... Juste une intuition prendre avec un peu de sel :)

3

Est-il nécessaire de fsync() après chaque fichier? Vous aurez peut-être plus de chance de laisser l'OS décider quand il faut écrire toutes les images mises en file d'attente sur la carte SD (en amortissant le coût de démarrage de la manipulation de la carte SD sur plusieurs images plutôt que sur chaque image).

Pouvez-vous fournir plus de détails sur votre plate-forme? Les temps d'E/S lents peuvent concerner d'autres processus sur le système, un contrôleur d'E/S lent, etc.

Vous pouvez également envisager d'utiliser un système de fichiers plus adapté au fonctionnement de la mémoire flash. FAT32 est plus commun que extN, mais un système de fichiers spécialement construit pour SD peut également être en ordre. JFFS est un bon exemple de cela.Vous obtiendrez probablement de meilleures performances avec un système de fichiers conçu pour Flash (par opposition aux supports magnétiques en rotation), et vous obtiendrez également de meilleures propriétés de niveau d'usure (et donc de durée de vie/fiabilité).

+0

pleaes noter JFFS et similaires ne sont pas une bonne idée pour certains périphériques flash, tels que CompactFlash, qui font leur propre nivellement d'usure. – Hasturkun

+1

Est-ce une mauvaise idée ou est-ce que le nivellement d'usure CompactFlash annule les avantages de JFFS? C'est une question honnête, je n'en ai aucune idée. Je suis d'accord que c'est certainement un meilleur choix pour les appareils flash «bruts». –

2

AFAIK certains disques flash ont des performances d'écriture vraiment mauvaises (en particulier les marques bon marché). Donc, si vous mesurez la vitesse d'écriture de votre application (y compris le temps requis pour fsync), qu'obtenez-vous? Il pourrait facilement être de l'ordre de très peu de mégaoctets par seconde, simplement parce que le matériel ne fonctionne pas mieux.

En outre, l'écriture apparemment peut être beaucoup plus lent si vous écrivez beaucoup de petits blocs au lieu d'un grand bloc (le disque flash peut seulement obtenir environ 10 écritures par seconde fait, dans les mauvais cas). Ceci est probablement quelque chose qui peut être atténué par le tampon du noyau, donc en utilisant fsync peut souvent ralentir l'écriture ...

btw. avez-vous mesuré les performances en écriture sur FAT32? Je suppose que c'est à peu près la même chose, mais sinon, peut-être y a-t-il encore de l'optimisation?

1

peut être cela vous aidera - Benchmarking Filesystems:

... J'ai été très surpris de la lenteur ext3 était dans l'ensemble, autant de distributions utilisent ce système de fichiers comme système de fichiers par défaut ...

et "ext3 fsync batching":

... Cette mesure patch le temps qu'il faut pour valider une transaction sur le disque, et sleeps basé sur la vitesse du disque sous-jacent.

4

Essayez d'ouvrir le fichier avec O_DIRECT et faire la mise en cache dans le niveau de l'application.

Nous avons rencontré le problème similaire lorsque nous mettions en œuvre un magnétoscope numérique fonction (enregistrement vidéo personnel) dans STB Box. L'astuce O_DIRECT a satisfait notre besoin finaly. (*)

Sans O_DIRECT. Les données de write() seront d'abord mises en mémoire cache dans le tampon du noyau, puis seront vidées dans le média lorsque vous appelez fsync ou lorsque le tampon du cache du noyau est plein. (**).

Avec O_DIRECT .Th noyau fera DMA directement à la mémoire physique pointée par le tampon de l'espace utilisateur passé en paramètre aux syscalls write. Il n'y aura donc pas de CPU et de bande passante mem dans les copies entre la mémoire de l'espace utilisateur et le cache noyau, et il n'y aura pas de temps processeur dans la gestion du cache (comme les recherches de cache, les verrous par page, etc.). (copié à partir here)

Je ne sais pas, il peut aussi résoudre votre problème, mais vous pouvez avoir un essai.

* Malgré le critize de Linus O_DIRECT, il a résolu nos problèmes.

** supposons que vous n'avez pas ouvert le fichier avec O_DSYNC ou O_SYNC

+0

Très intéressant. Je pense que le problème avec la mise en cache est que toutes les demandes d'E/S (sur ce système particulier) passent par une seule file d'attente. Si un périphérique de type bloc (le disque) est en cours de rinçage, ses informations de journalisation sont alors bloquées, alors l'écriture non liée à un autre périphérique bloc (carte SD) sera bloquée. Je vais essayer cette chose O_DIRECT. – shodanex

0

Pour tous ceux qui lisent ceci et en utilisant un noyau 2.6.28 ci-dessus, la recommandation est d'utiliser ext4 au lieu de ext3, qui est un système de fichiers que vous peut accorder pour de meilleures performances. Les meilleures performances sont obtenues en mode data = writeback, où les données ne sont pas journalisées. Lire la section Data Mode de https://www.kernel.org/doc/Documentation/filesystems/ext4.txt.

Si vous avez une partition déjà créée, dites /dev/sdb1, alors ce sont des mesures qui peuvent être utilisés pour le formater avec ext4 sans journaling:

mkfs.ext4 /dev/sdb1 -L jp # Creates the ext4 filesystem 
tune2fs -o journal_data_writeback /dev/sdb1 # Set to writeback mode 
tune2fs -O ^has_journal /dev/sdb1 # Disable journaling 
sudo e2fsck -f /dev/sdb1 # Filesystem check is required 

Ensuite, vous pouvez monter cette partition (ou définir un entrée /etc/fstab si vous savez ce que vous faites) avec les drapeaux correspondants:

mount -t ext4 -O noatime,nodirame,data=writeback /dev/mmcblk0p1 /mnt/sd 

Passer de ext3 à un système de fichiers ext4 optimisé devrait être une différence radicale. Et, bien sûr, si votre carte SD est plus rapide, cela devrait aider (c'est-à-dire la classe 10).

Voir aussi https://developer.ridgerun.com/wiki/index.php/High_performance_SD_card_tuning_using_the_EXT4_file_system