2010-01-03 21 views
8

Tengo un programa que lee datos de 2 archivos de texto y luego guarda el resultado en otro archivo. Dado que hay muchos datos para leer y escribir que causan un golpe de rendimiento, quiero paralizar las operaciones de lectura y escritura.Cómo paralelizar la lectura y escritura de archivos

Mi idea inicial es usar 2 hilos como ejemplo, un hilo de lectura/escritura desde el principio y otro hilo de lectura/escritura desde la mitad del archivo. Como mis archivos están formateados como líneas, no como bytes (cada línea puede tener diferentes bytes de datos), buscar por byte no me funciona. Y la solución en la que podría pensar es use getline() para omitir las líneas anteriores primero, lo que podría no ser eficiente.

¿Hay alguna manera de buscar una línea específica en un archivo? o ¿tiene alguna otra idea para paralizar la lectura y escritura de archivos?

Medio Ambiente: Win32, C++, NTFS, solo disco duro

Gracias.

-Dbger

+1

¿Cuál es su sistema de archivos y qué hardware usa? si solo tiene un controlador/disco, puede que no sea eficiente hacer E/S paralelas – Anycorn

+0

, entonces ¿eso significa que paralizar la E/S del disco siempre causará una degradación del rendimiento si solo se lee/escribe en el mismo disco? –

+1

Dbger: si usa un disco duro, sí. – Mike

Respuesta

18

En términos generales, usted no quiere poner en paralelo/S de disco. A los discos duros no les gusta la E/S aleatoria porque tienen que buscar continuamente para llegar a los datos. Suponiendo que no está utilizando RAID, y está utilizando discos duros en lugar de memoria de estado sólido, verá una degradación grave del rendimiento si paraleliza la E/S (incluso cuando se utilizan tecnologías como esas, aún se puede ver algún rendimiento). degradación al hacer muchas E/S aleatorias).

Para responder a su segunda pregunta, realmente no hay una buena manera de buscar cierta línea en un archivo; solo puede buscar explícitamente un desplazamiento de bytes utilizando la función read (consulte this page para obtener más detalles sobre cómo usarlo.

+0

Por lo tanto, en la lectura/escritura de archivos, la búsqueda de disco cuesta la mayor parte del tiempo, que es el caso en el entorno de multi-threading, ¿verdad? –

+2

Sí, el tiempo de búsqueda de disco generalmente será el cuello de botella en un entorno de E/S multiproceso. Debería intentar serializar su E/S siempre que sea posible. – Mike

+0

Gracias Mike, solo para confirmar, esto solo se aplica cuando se lee un solo archivo, o también se aplica cuando se leen varios archivos (subproceso 1 leer archivo1, subproceso2 leer archivo2) –

1

Esto no es realmente una respuesta a su pregunta, sino un rediseño (que todos odiamos) pero no puedo evitar hacerlo). Como ya se mencionó, tratar de acelerar las E/S en un disco duro con múltiples hilos probablemente no ayude.

Sin embargo, podría ser posible usar otro enfoque dependiendo de la sensibilidad de los datos , necesidades de rendimiento, tamaño de datos, etc. No sería difícil crear una estructura en la memoria que mantenga una imagen de los datos y permita actualizaciones fáciles/rápidas de las líneas de texto en cualquier lugar de los datos. Luego, podría usar un hilo dedicado que simplemente monitorea esa estructura y cuyo trabajo es escribir los datos en el disco. Escribir datos secuencialmente en el disco puede ser extremadamente rápido; puede ser mucho más rápido que buscar secciones diferentes al azar y escribirlas en pedazos.

+0

Cuando escribo datos de 2M en un archivo de texto, secuencialmente, cuesta aproximadamente 1 segundo en mi máquina, lo cual es demasiado lento para mí. En cuanto a la lectura, para formar una estructura de memoria del archivo, necesito leer los datos primero, que también es demasiado lento para cumplir con mis requisitos. Sin embargo, investigaría los temas sobre la superposición de E/S y el archivo de mapa de memoria para ver si eso ayuda. –

+1

1 segundo para escribir 2MB? Eso parece increíblemente lento. Acabo de ejecutar una prueba que escribe 10M en un archivo en aproximadamente 100ms, y mi PC no es una máquina de velocidad real (3.2GHz e I * think * 7200rpm drive). ¿Qué API estás usando para abrir y escribir en el archivo? –

+0

Estoy usando std :: ofstream para guardar muchos datos separados en un bucle. como "for (...) {streamOut << x; streamOut << y}", y también tengo un disco de 7200rpm con una CPU de doble núcleo de 2.16GHz –

2

Poner en cola varias lecturas y escrituras no ayudará cuando se ejecuta en un disco. Si su aplicación también realizó un montón de trabajo en la CPU, entonces podría hacer sus lecturas y escrituras asincrónicamente y dejar que la CPU trabaje mientras la E/S del disco ocurre en segundo plano. Alternativamente, obtenga un segundo disco duro físico: lea de uno, escriba en el otro. Para conjuntos de datos de tamaño modesto que a menudo es efectivo y bastante más económico que escribir código.

+0

Use un hilo de fondo para escribir gradualmente los datos de salida cuando la CPU está ocupada con la informática, es una buena idea. Pero en cuanto a la lectura, no se puede hacer mucho trabajo ya que los datos no están listos. –

+0

Dbger, depende de la naturaleza de sus datos. Si puede poner en cola una segunda búsqueda asíncrona para que se satisfaga mientras procesa los datos de la primera recuperación, estará en el negocio. De nuevo, es más efectivo si el disco no está ocupado con otras E/S, por lo que posiblemente no sea aplicable a su situación inmediata. –

Cuestiones relacionadas