¿Estrategias de E / S para problemas computacionales con grandes conjuntos de datos?

15

Mi grupo de investigación se centra en la dinámica molecular, que obviamente puede generar gigabytes de datos como parte de una sola trayectoria que luego debe analizarse.

Varios de los problemas que nos preocupan implican correlaciones en el conjunto de datos, lo que significa que necesitamos hacer un seguimiento de grandes cantidades de datos en la memoria y analizarlos, en lugar de utilizar un enfoque más secuencial.

Lo que me gustaría saber es cuáles son las estrategias más eficientes para manejar E / S de grandes conjuntos de datos en scripts. Normalmente usamos scripts basados ​​en Python porque hace que la codificación de la E / S del archivo sea mucho menos dolorosa que C o Fortran, pero cuando tenemos decenas o cientos de millones de líneas que deben procesarse, no está tan claro cuál es el mejor enfoque. . ¿Deberíamos considerar hacer la entrada del archivo como parte del código en C, o es otra estrategia más útil? (¿Simplemente precargar toda la matriz en la memoria será mejor que una serie de lecturas secuenciales de "fragmentos" (orden de megabytes)?

Algunas notas adicionales:

  • Principalmente buscamos herramientas de secuencias de comandos para el procesamiento posterior, en lugar de herramientas "en línea", de ahí el uso de Python.

  • Como se indicó anteriormente, estamos haciendo simulaciones MD. Un tema de interés son los cálculos de difusión, para los cuales necesitamos obtener el coeficiente de difusión de Einstein: Esto significa que realmente necesitamos cargar todos los datos en la memoria antes de comenzar el cálculo, todos los fragmentos de datos ( registros de tiempos individuales) interactuarán entre sí.

    re=16 6limΔt(X(t+Δt)-X(t))2
aeismail
fuente

Respuestas:

6

Supongo que su pregunta proviene de la observación de que la E / S causa una sobrecarga significativa en todo su análisis. En ese caso, puede intentar superponer E / S con el cálculo.

Un enfoque exitoso depende de cómo accede a los datos y el cálculo que realiza en esos datos. Si puede identificar un patrón, o el acceso a diferentes regiones de los datos se conoce de antemano, puede intentar buscar previamente los "siguientes fragmentos" de datos en segundo plano mientras procesa los "fragmentos actuales".

Como ejemplo simple, si solo recorre su archivo una vez y procesa cada línea o conjunto de líneas, puede dividir la secuencia en trozos de líneas (o MB). Luego, en cada iteración sobre los fragmentos, puede cargar el fragmento i + 1 mientras procesa el fragmento i.

Su situación puede ser más compleja y necesitar soluciones más complejas. En cualquier caso, la idea es realizar la E / S en segundo plano mientras el procesador tiene algunos datos para trabajar. Si proporciona más detalles sobre su problema específico, es posible que podamos analizarlo más a fondo;)

---- Versión extendida después de dar más detalles ----

No estoy seguro de entender la notación, pero bueno, como dijiste, la idea es una interacción total. También mencionas que los datos pueden caber en la RAM. Luego, comenzaría midiendo el tiempo para cargar todos los datos y el tiempo para realizar el cálculo. Ahora,

  • si el porcentaje de E / S es bajo (bajo, ya que no le importa la sobrecarga, sea lo que sea: 0.5%, 2%, 5%, ...), simplemente use el enfoque simple: cargar datos a la vez, y calcular. Ahorrará tiempo para aspectos más interesantes de su investigación.

  • Si no puede pagar los gastos generales, es posible que desee ver lo que sugirió Pedro. Tenga en cuenta lo que Aron Ahmadia mencionó y pruébelo antes de realizar una implementación completa.

  • Si lo anterior no es satisfactorio, optaría por una implementación fuera del núcleo [1]. Dado que parece que está realizando cálculos en datos, hay esperanza :) Algunos pseudocódigo (suponiendo que los resultados de su análisis encajen en la RAM):norte2norte

    cargar trozo1 y trozo2
    para trozos i = 1 a n
        cargar asincrónicamente parte i + 1
        para trozos en j = i + 1 a n
            cargar asincrónicamente parte j + 1
            calcular con fragmentos i, j (* para la primera iteración, estos son los fragmentos precargados 1 y 2 *)

Nota: este es un pseudocódigo rápido y sucio, sería necesario ajustar los índices.

Para implementar esto, es común usar el llamado doble búfer . En términos generales: divide la memoria en dos espacios de trabajo; mientras los datos se cargan en segundo plano en el espacio de trabajo 1, el procesador computa con los datos en el espacio de trabajo 2. En cada iteración, intercambie el rol.

Lo siento, no puedo encontrar una buena referencia en este momento.

[1] Un algoritmo fuera del núcleo incorpora algún mecanismo para tratar (eficientemente) los datos que residen en el disco. Se llaman fuera de núcleo en lugar de dentro de núcleo ("en RAM").

Diego
fuente
7

He tenido que lidiar con problemas similares antes, y mi solución favorita es usar E / S mapeadas en memoria , aunque en C ...

El principio subyacente es bastante simple: en lugar de abrir un archivo y leerlo, lo carga directamente en la memoria y accede a él como si fuera una gran matriz. El truco que lo hace eficiente es que el sistema operativo en realidad no carga el archivo , solo lo trata como una memoria intercambiada que debe cargarse. Cuando accede a cualquier byte dado en su archivo, la página de memoria para esa parte del archivo se intercambia en la memoria. Si sigue accediendo a diferentes partes del archivo y la memoria se pone apretada, las partes menos utilizadas se cambiarán de nuevo, ¡automáticamente!

Una búsqueda rápida en Google me dice que esto también está disponible para Python: 16.7. mmap: soporte de archivos mapeados en memoria , pero no sé lo suficiente sobre Python para saber si realmente es lo mismo.

Pedro
fuente
1
Solo asegúrese de medir y probar antes de implementar algo como mmapen su código principal. Muchos sistemas operativos modernos ofrecen un rendimiento similar entre los regulares readcon menos complicaciones. (Además, sí, mmap en Python proporciona una interfaz portátil para los mapas de memoria de Windows y UNIX).
Aron Ahmadia
1

¿Quizás pueda usar Cython en las secciones de E / S de su archivo y convertir esta parte en código C?

asmático
fuente