He creado una aplicación que hace lo siguiente:¿Cuántos archivos pequeños o uno grande? (O, sobrecarga de abrir y cerrar el archivo asas) (C++)
- Hacer algunos cálculos, escritura datos calculados a un archivo - Repita para 500.000 veces (sobre todo, escriba 500,000 archivos uno después del otro) - repita 2 veces más (sobre todo, se escribieron 1,5 millones de archivos).
- Leer datos de un archivo, hacer algunos cálculos intensos con los datos del archivo - para repetir 1.500.000 iteraciones (iterar sobre todos los archivos escritos en el paso 1.)
- repita el paso 2 por 200 iteraciones.
Cada archivo es ~ 212k, así que sobre todo tengo ~ 300Gb de datos. Parece que todo el proceso lleva ~ 40 días en una CPU Core 2 Duo con 2.8 Ghz.
Mi problema es (como probablemente puede adivinar) es el tiempo que lleva completar todo el proceso. Todos los cálculos son en serie (cada cálculo depende del anterior), por lo que no puedo realizar un paralelo de este proceso con diferentes CPU o PC. Estoy tratando de pensar cómo hacer que el proceso sea más eficiente y estoy bastante seguro de que la mayor parte de la sobrecarga va al acceso al sistema de archivos (duh ...). Cada vez que accedo a un archivo, le abro un identificador y luego lo cierro una vez que termino de leer los datos.
Una de mis ideas para mejorar el tiempo de ejecución era usar un archivo grande de 300Gb (o varios archivos grandes de 50Gb cada uno), y luego solo usaría un archivo abierto y simplemente buscaría cada dato relevante y leería pero no soy el responsable de abrir y cerrar los identificadores de archivo. ¿Alguien puede arrojar algo de luz sobre esto?
Otra idea que tuve fue intentar agrupar los archivos en archivos ~ 100Mb más grandes y luego leería 100Mb cada vez en lugar de muchas lecturas de 212k, pero esto es mucho más complicado de implementar que la idea anterior.
De todos modos, si alguien puede darme algún consejo sobre esto o tiene alguna idea de cómo mejorar el tiempo de ejecución, ¡lo agradecería!
Gracias.
actualización de perfiles:
Me corrió un generador de perfiles en el proceso, parece que los cálculos tienen el 62% de tiempo de ejecución y la lectura de archivos se realiza el 34%. Lo que significa que incluso si recorté milagrosamente los costos de E/S de archivo por un factor de 34, aún me quedan 24 días, lo cual es una gran mejora, pero todavía mucho tiempo :)
¿Ha considerado almacenarlo en una base de datos? –
Lo he considerado, pero ¿eso haría que la extracción de datos fuera más rápida? – dudico
Has dicho que estás bastante seguro de que abrir/cerrar los archivos es un cuello de botella. ¿Es esto una corazonada basada en perfilar el programa o es más bien una corazonada general? Si es lo último, te sugiero que primero perfile tu código. –