2012-05-20 19 views
8

Tengo que leer una matriz 8192x8192 en la memoria. Quiero hacerlo lo más rápido posible.
Ahora mismo tienen esta estructura:Lectura de archivos más rápida en una aplicación multiproceso

char inputFile[8192][8192*4]; // I know the numbers are at max 3 digits 
int8_t matrix[8192][8192]; // Matrix to be populated 

// Read entire file line by line using fgets 
while (fgets (inputFile[lineNum++], MAXCOLS, fp)); 

//Populate the matrix in parallel, 
for (t = 0; t < NUM_THREADS; t++){ 
    pthread_create(&threads[t], NULL, ParallelRead, (void *)t); 
} 

En la función ParallelRead, yo analizo cada línea, hago atoi y poblar la matriz. El paralelismo es la línea en cuanto a como el hilo t analiza línea t, t+ 1 * NUM_THREADS..

En un sistema de dos hilos con 2 hilos, esto toma

Loading big file (fgets) : 5.79126 
Preprocessing data (Parallel Read) : 4.44083 

¿Hay una manera de optimizar esta más lejos?

+3

Quizás podría iniciar los hilos de relleno en paralelo con la E/S, ya que hay suficientes datos disponibles. – vanza

+0

Para ser sincero, estoy un poco sorprendido de que hayas logrado * * mejorar el rendimiento leyendo el mismo archivo de varios hilos ... Cuando se compara, ¿estás asegurándote de que el archivo realmente se lee del disco y no desde el caché? – NPE

+0

@aix i hav usó 2 hilos, por ejemplo. He paralelizado la parte de preprocesamiento, esto es después de que los datos se leen en la memoria. – sud03r

Respuesta

2

Una cosa que vale la pena considerar es la asignación de dos búferes de entrada más pequeños (digamos que serán 200 líneas cada uno).

Luego, tenga un hilo de lectura de datos en los búferes de entrada. Cuando un búfer de entrada está lleno, páselo a un segundo hilo que realice el análisis sintáctico. Este segundo subproceso podría usar un grupo de subprocesos para el análisis simultáneo (marque abrirMP).

Deberá usar bloqueos/mutexes para garantizar que cualquiera de los subprocesos tenga acceso exclusivo.

Esto sería mejor porque el análisis ahora es simultáneo con la lectura del archivo, y el acceso de memoria al búfer es más local y se ajustará a la memoria caché de la CPU. Esto puede mejorar la velocidad de lectura y análisis.

Si fgets es el cuello de botella, también puede leer el archivo en la memoria como binario. Esto podría mejorar la velocidad de lectura, pero requerirá que realice un análisis adicional y hará que la optimización mencionada sea más difícil de llevar a cabo.

2

Pruebe un hilo padre que cargue la matriz de caracteres usando algo como fread para cargar todo en 1 io como una gran secuencia grande.

Haga que el padre camine la cuerda, y encuentre 1 línea, o calcule dónde se basa la primera línea en los tamaños. Entregue el procesamiento de esa línea a un hilo. Siguiente línea, enjuague, repita, hasta EOF. Sincroniza con los hilos. Hecho.

1

El mejor rendimiento que puede obtener con E/S de archivo es a través de la asignación de memoria. This is an example. Comenzaría desde un diseño con un solo hilo y si el procesamiento posterior a la carga resulta ser un cuello de botella, hágalo paralelo.

22

Es una mala idea hacerlo de esta manera. Los hilos pueden obtener sus ciclos de CPU más si tiene suficientes núcleos, pero todavía tiene un solo disco duro. Entonces, inevitablemente, los hilos no pueden mejorar la velocidad de lectura de los datos del archivo.

En realidad lo hacen mucho peor. Leer datos de un archivo es más rápido cuando accede al archivo secuencialmente. Eso minimiza la cantidad de cabezales lectores, de lejos la operación más costosa en una unidad de disco. Al dividir la lectura en varios hilos, cada uno leyendo una parte diferente del archivo, hará que la cabeza del lector salte constantemente hacia adelante y hacia atrás. Muy, muy mal para el rendimiento.

Utilice solamente un hilo para leer los datos del archivo. Es posible que pueda superponerlo con algunos ciclos computacionales en los datos del archivo iniciando un hilo una vez que se carga una porción de los datos del archivo.

Do ten cuidado con el efecto de prueba.Cuando vuelve a ejecutar su programa, normalmente después de ajustar un poco su código, es probable que el programa pueda encontrar datos de archivos en la caché del sistema de archivos para que no tenga que leerlos desde el disco. Eso es muy rápido, la velocidad del bus de memoria, una copia de memoria a memoria. Muy probablemente en su conjunto de datos, ya que no es muy grande y se ajusta fácilmente a la cantidad de RAM que tiene una máquina moderna. Esto no ocurre (típicamente) en una máquina de producción. Así que asegúrese de borrar la caché para obtener números realistas, sea lo que sea que tome su sistema operativo.

+2

no lee el archivo en paralelo, está convirtiendo la cadena en int8_t's en paralelo desde la memoria. No hay nada de malo en eso. – kratenko

+0

Nunca dije que hubiera nada de malo en eso. De hecho, recomendé superponer eso con el hilo que lee los datos. –

Cuestiones relacionadas