2008-10-10 31 views
5

Estoy escribiendo una pequeña aplicación, que consiste en escribir imágenes jpeg a una velocidad constante en una tarjeta SD. Elijo un sistema de archivos EXT3, pero el mismo comportamiento se observó con un sistema de archivos EXT2.Rendimiento de escritura de la tarjeta SD

Mi lazo de la escritura se parece a esto:

get_image() 
fwrite() 
fsync() 

O así:

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

que también muestran algunas estadísticas de tiempo, y puedo ver mi programa se bloquea en algún momento durante varios segundos. La tasa promedio sigue siendo buena, porque si conservo las imágenes entrantes en una fifo, entonces escribiré muchas imágenes en un corto período de tiempo después de dicha pérdida. ¿Sabes si es un problema con el sistema operativo o si está relacionado con la tarjeta SD en sí? ¿Cómo podría acercarme más a tiempo real? No necesito un fuerte tiempo real, pero estar estancado durante varios segundos no es aceptable.

Un poco de precisión: Sí, es necesario hacer fsync después de cada archivo, porque quiero que la imagen esté en el disco, no en algún usuario o en el búfer del kernel. Sin fsyncing, tengo mucho mejor rendimiento, pero todavía inaceptable. No creo que sea un problema de búfer, ya que el primer bloqueo ocurre después de que se escribieron 50 Mbytes. Y de acuerdo con la página man, fsync está aquí precisamente para garantizar que no haya datos almacenados en búfer.

precisión con respecto a la tasa promedio de escritura: me escribo a un ritmo que es sostenible por la tarjeta que estoy utilizando. Si apilo la imagen entrante mientras espero que se complete una fsync, después de esta parada la tasa de transferencia de escritura aumentará y rápidamente volveré a la tasa promedio. La tasa de transferencia promedio es de alrededor de 1,4 MBytes/s.

El Systeme es un moderno ordenador portátil con Ubuntu 8.04 con la acción Kee (2.6.24.19)

Respuesta

1

No estoy muy bien informado en esta área, pero los síntomas que usted describe suena un montón, como llenar un búfer. Es posible que esté llenando un búfer en la grabadora de archivos o en el dispositivo de E/S que se comunica con la tarjeta SD. Luego debe esperar hasta que realmente escriba los datos en la tarjeta (vaciando así el búfer) antes de poder escribir más. Las tarjetas SD no son particularmente rápidas. Si puede encontrar una manera de verificar si realmente se están escribiendo datos en la tarjeta durante estas pausas, eso verificaría mi teoría. Algunos lectores de tarjetas tienen un LED que parpadea cuando se accede a los datos, lo que probablemente sería un buen indicador.

Apenas un presentimiento ... tomarlo con un poco de sal :)

3

¿Es necesario fsync() después de cada archivo? Puede ser mejor que el SO decida cuándo es un buen momento escribir todas las imágenes en cola en la tarjeta SD (amortizando el costo inicial de manipular el sistema de archivos de la tarjeta SD en muchas imágenes, en lugar de incurrir en ello para cada imagen).

¿Puede proporcionarnos más detalles sobre su plataforma? Los tiempos de E/S lentas pueden tener que ver con otros procesos en el sistema, un controlador lento de E/S, etc.

También podría considerar usar un sistema de archivos más adecuado para el funcionamiento de la memoria flash. FAT32 es más común que extN, pero un sistema de archivos creado especialmente para SD también puede estar en orden. JFFS es un buen ejemplo de esto.Probablemente obtendrá un mejor rendimiento con un sistema de archivos diseñado para flash (a diferencia de los medios magnéticos giratorios), y también obtendrá mejores propiedades de nivelación de desgaste (y por lo tanto vida útil/confiabilidad del dispositivo).

+0

pleaes nota JFFS y similares no son una buena idea para algunos dispositivos flash, como CompactFlash, que hacen su propia nivelación de desgaste. – Hasturkun

+1

¿Son una mala idea o la nivelación de desgaste de CompactFlash simplemente niega los beneficios de JFFS? Es una pregunta honesta, no tengo idea. Estoy de acuerdo en que sin duda es una mejor opción para dispositivos flash 'crudos'. –

2

AFAIK algunos discos flash tienen un rendimiento de escritura realmente malo (especialmente marcas baratas). Entonces, si mide la velocidad de escritura de su aplicación (incluido el tiempo requerido para fsync), ¿qué obtiene? Puede ser fácilmente del orden de muy pocos megabytes por segundo, solo porque el hardware no funciona mejor.

Además, al parecer, la escritura puede ser mucho más lenta si escribe muchos bloques pequeños en lugar de uno grande (el disco flash podría obtener aproximadamente 10 escrituras por segundo, en los casos malos). Esto es probablemente algo que puede ser mitigado por el buffer del kernel, por lo que usar fsync con frecuencia podría ralentizar la escritura ...

Btw. ¿midió el rendimiento de escritura en FAT32? Supongo que es más o menos lo mismo, pero si no, ¿tal vez todavía hay alguna optimización disponible?

1

puede ser que esto ayudará - Benchmarking Filesystems:

... Me ha sorprendido cómo ext3 lento era en general, ya que muchas distribuciones usan este sistema de archivos como su sistema de archivos por defecto ...

y "ext3 fsync batching":

... Este parche mide el tiempo que tarda en confirmar una transacción en el disco, y duerme basa en la velocidad del disco subyacente.

4

Intente abrir el archivo con O_DIRECT y haga el almacenamiento en caché en el nivel de la aplicación.

Nos encontramos con el problema similar cuando estábamos implementando una función de PVR (grabación de video personal) en STB Box. El truco O_DIRECT satisfizo finalmente nuestra necesidad. (*)

Sin O_DIRECT. Los datos de write() se almacenarán primero en caché en el búfer del núcleo y luego se vacían al medio cuando se llama al fsync o cuando el búfer del caché del kernel está lleno. (**).

Con O_DIRECT. El kernel hará DMA directamente a la memoria física apuntada por el búfer del espacio de usuario pasado como parámetro al write syscalls. Por lo tanto, no se gastará CPU ni ancho de banda en las copias entre la memoria del espacio de usuario y la memoria caché del kernel, y no habrá tiempo de CPU en kernel en la gestión de la caché (como búsquedas en caché, bloqueos por página, etc.). (copiado de here)

No estoy seguro de que también pueda resolver su problema, pero es posible que desee intentarlo.

* A pesar del critize de O_DIRECT de Linus, resolvió nuestros problemas.

** supongamos que no haya abierto el archivo con O_DSYNC o O_SYNC

+0

Muy interesante. Creo que el problema con el almacenamiento en caché es que todas las solicitudes de E/S (en este sistema en particular) pasan por una sola cola. Si un dispositivo de bloque (el disco) está descargando su información de diario, se bloqueará la escritura no relacionada a otro dispositivo de bloque (tarjeta SD). Voy a probar esta cosa O_DIRECT. – shodanex

0

Para cualquiera que lea esto y se utiliza un kernel 2.6.28 anterior, la recomendación es utilizar ext4 en lugar de ext3, que es un sistema de archivos que se puede sintonizar para un mejor rendimiento. El mejor rendimiento se obtiene en el modo data = writeback, donde los datos no se registran por diario. Lea la sección Modo de datos desde https://www.kernel.org/doc/Documentation/filesystems/ext4.txt.

Si tiene una partición ya creada, por ejemplo /dev/sdb1, entonces estos son algunos pasos que se pueden utilizar para dar formato con ext4 sin registro en diario:

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 

A continuación, se puede montar esta partición (o marcar una /etc/fstab entrada si usted sabe lo que está haciendo) con las banderas correspondientes:

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

Pasar de un sistema de ficheros ext3 a ext4 optimizado debe haber una diferencia drástica. Y, por supuesto, si su tarjeta SD es más rápida, debería ayudar (es decir, clase 10).

Ver también https://developer.ridgerun.com/wiki/index.php/High_performance_SD_card_tuning_using_the_EXT4_file_system

Cuestiones relacionadas