2011-01-25 22 views
8

Estoy desarrollando una aplicación C++ (que se ejecuta en un cuadro de Linux) que es muy intensa para leer archivos de registro y escribir resultados derivados en el disco. Me gustaría saber cuáles son las mejores prácticas para optimizar este tipo de aplicaciones:¿Cuáles son las mejores prácticas para la lectura y escritura de datos intensivos en una HD?

  • ¿Qué ajustes del sistema operativo mejoran el rendimiento?
  • ¿Qué patrones de programación aumentan el rendimiento IO?
  • ¿Es una medida útil preprocesar los datos (convertir a binario, comprimir datos, etc. ...)?
  • ¿Los datos de fragmentación/almacenamiento en búfer ayudan en el rendimiento?
  • ¿Qué capacidades de hardware debo tener en cuenta?
  • ¿Qué prácticas son mejores para perfilar y medir el rendimiento en estas aplicaciones?
  • (aquí expresar la preocupación que me falta)

¿Hay una buena lectura en el que podía conseguir los fundamentos de esta manera pude adaptar el know-how existente para mi problema?

Gracias

+0

mantener los datos en memorias intermedias y escribir menos posible, es muy lento. – BlackBear

Respuesta

6

compresión sin duda pueden ayudar mucho y es mucho más simple que ajustar el sistema operativo. Consulte el soporte gzip y bzip2 en la biblioteca Boost.IOStreams. Sin embargo, esto tiene su costo en el procesador.

La medición de este tipo de trabajos comienza con el comando time. Si el tiempo del sistema es muy alto en comparación con el tiempo del usuario, entonces su programa pasa mucho tiempo haciendo llamadas al sistema. Si el tiempo del reloj de pared ("real") es alto en comparación con el tiempo del sistema y del usuario, está esperando el disco o la red. El comando top que muestra un uso de CPU significativamente menor que el 100% para el programa también es un signo de embotellamiento de E/S.

+0

Obtenemos alrededor de 3 veces la aceleración con duing 'zcat bigfile.gz | ourprogram' vs 'ourprorogram nos

2

Obtenga información sobre el volumen desde el que estará escribiendo/leyendo y cree búferes que coincidan con las características del volumen. p.ej. 10 * clusterSize.

El almacenamiento en búfer ayuda mucho, al igual que minimizar la cantidad de escritura que tiene que hacer.

3

1) Verifique el tamaño del sector de su disco.
2) Asegúrese de que el disco esté desfragmentado.
3) Leer datos que son "locales" a las últimas lecturas que ha hecho para mejorar la localidad de caché (el sistema operativo realiza la caché y muchos discos duros también tienen un caché integrado).
4) Escribir datos contiguamente.

Para el rendimiento de escritura, almacena en caché los bloques de datos en la memoria hasta que llegues a un múltiplo del tamaño del sector y luego inicies una escritura asíncrona en el disco. No sobrescriba los datos que se escriben actualmente hasta que pueda estar seguro de que los datos se han escrito (es decir, sincronice la escritura). El doble o triple buffering puede ayudar aquí.

Para obtener el mejor rendimiento de lectura, puede duplicar lecturas de búfer. Así que digamos que almacena en caché 16K bloques en lectura. Lea los primeros 16K del disco en el bloque 1. Inicie una lectura asincrónica de los 2º 16K en el bloque 2. Comience a trabajar en el bloque 1. Cuando haya terminado con el bloque 1 sincronice la lectura del bloque 2 e inicie una lectura asíncrona en el bloque 1 de el tercer bloque de 16K en el bloque 1. Ahora trabaje en el bloque 2. Cuando termine de sincronizar la lectura del tercer bloque de 16K, inicie una lectura asíncrona del 4º 16K en el bloque 2 y trabaje en el bloque 1.Enjuague y repita hasta que haya procesado todos los datos.

Como ya se mencionó, se perderán menos datos de lectura del disco, por lo que puede valer la pena leer datos comprimidos y pasar el tiempo de CPU expandiendo cada bloque en lectura. Igualmente, la compresión del bloque antes de escribir le ahorrará tiempo de disco. Si esto es un triunfo o no, realmente dependerá de cuán intensivo sea el procesamiento de los datos.

Además, si el procesamiento en los bloques es asimétrico (es decir, el bloque de procesamiento 1 puede tardar 3 veces más que el bloque de procesamiento 2), considere la posibilidad de almacenar tres o más memorias intermedias para lecturas.

2

Como se indicó aquí, debe verificar el tamaño del bloque. Lo haces con funciones familiares de estadísticas. En struct stat, esta información se encuentra en el campo st_blksize.

Lo segundo es la función posix_fadvise(), que da consejos al sistema operativo sobre la búsqueda. Le dice al sistema cómo va a usar el archivo (o incluso el fragmento de un archivo). Encontrarás más en la página de manual.

+0

posix_fadvise() No lo sabía, gracias hombre! :RE –

0

En Windows, utilice CreateFile() con FILE_FLAG_SEQUENTIAL_SCAN y/o FILE_FLAG_NO_BUFFERING en lugar de fopen() - al menos para escribir esto devuelve inmediatamente en vez de esperar que los datos para limpiar el disco

Cuestiones relacionadas