2012-06-21 15 views
7

Estoy trabajando para optimizar un programa de análisis de flujo de fluidos y transferencia de calor escrito en Fortran. Cuando intento ejecutar simulaciones de malla cada vez más grandes, me encuentro con problemas de limitación de memoria. La malla, sin embargo, no es tan grande. Solo 500,000 células y cacahuetes pequeños para que se ejecute un código CFD típico. Incluso cuando solicito 80 GB de memoria para mi problema, se cuelga debido a la insuficiente memoria virtual.Administración de memoria Fortran array

Tengo algunas conjeturas sobre qué matrices están acaparando toda esa memoria. Uno en particular está siendo asignado a (28801,345600). Corrígeme si me equivoco en mis cálculos, pero una matriz de doble precisión es de 8 bits por valor. Entonces, ¿el tamaño de esta matriz sería 28801 * 345600 * 8 = 79.6 GB?

Ahora, creo que la mayor parte de esta matriz termina siendo ceros durante el cálculo, por lo que no es necesario almacenarlos. Creo que puedo cambiar el algoritmo de la solución para que solo almacene los valores distintos de cero para trabajar en una matriz mucho más pequeña. Sin embargo, quiero estar seguro de que estoy buscando las matrices correctas para reducir su tamaño. Entonces, primero, ¿calculé correctamente el tamaño de la matriz de arriba? Y segundo, ¿hay alguna manera de que Fortran muestre los tamaños de matriz en MB o GB durante el tiempo de ejecución? Además de imprimir las matrices más intensivas en memoria, me interesaría ver cómo cambian los requisitos de memoria del código durante el tiempo de ejecución.

+3

¿Cuánta memoria real tiene en la máquina en la que está ejecutando esto? Además, está equivocado en su suposición * la precisión * doble es de 8 bytes, no de 8 bits. Eso da alrededor de 74.16 GB de datos (potencias de 1024, no 1000). Además, estoy en lo cierto al suponer que está haciendo 4 días de datos (345600 segundos = 60 * 60 * 24 * 4) –

+0

Mike, esto se está ejecutando en un clúster con hasta 96 GB de memoria por nodo que puedo solicitud. Perdón por la confusión entre bytes y bits, y gracias por aclarar eso, pero estoy en el estadio correcto allí, así que el tamaño de la matriz definitivamente es un problema. Y no, ese 345600 está relacionado con la cantidad de celdas de la malla modelo y no tiene nada que ver con el tiempo. – rks171

+0

@ user104629: Una de las razones podría ser que no puede asignar una matriz contigua de 80 GB de memoria. –

Respuesta

4

El uso de memoria es un concepto bastante vagamente definido en sistemas con memoria virtual. Puede tener grandes cantidades de memoria asignadas (gran tamaño de memoria virtual), pero solo una pequeña parte de ella se está utilizando realmente (pequeño residente con tamaño de conjunto - RSS).

Los sistemas Unix proporcionan la llamada al sistema getrusage(2) que devuelve información sobre la cantidad de recursos del sistema en uso por la cadena de llamada/proceso/proceso secundarios. En particular, proporciona el valor máximo del RSS alcanzado desde que se inició el proceso. Puede escribir una función de ayudante C de Fortran que llame al getrusage(2) y devolver el valor del campo ru_maxrss de la estructura rusage.

Si está ejecutando en Linux y no le importa la portabilidad, entonces puede simplemente abrir y leer desde /proc/self/status. Es un texto simple pseudofile que entre otras cosas contiene varias líneas con estadísticas sobre el uso de la memoria virtual de proceso:

... 
VmPeak:  9136 kB 
VmSize:  7896 kB 
VmLck:   0 kB 
VmHWM:  7572 kB 
VmRSS:  6316 kB 
VmData:  5224 kB 
VmStk:  88 kB 
VmExe:  572 kB 
VmLib:  1708 kB 
VmPTE:  20 kB 
... 

Explicación de los diferentes campos - here. Lo que más le interesa es VmData, , VmHWM y VmSize. Puede abrir /proc/self/status como un archivo normal con OPEN() y procesarlo por completo en su código Fortran.

Consulte también qué limitaciones de memoria se establecen con ulimit -a y ulimit -aH. Es posible que esté excediendo el límite de tamaño de la memoria virtual dura. Si está enviando trabajos a través de un administrador de recursos distribuidos (por ejemplo, SGE/OGE, Torque/PBS, LSF, etc.), compruebe que solicita suficiente memoria para el trabajo.

+1

Genial, gracias por el consejo. La portabilidad no es una preocupación para mí, así que creo que iré con la ruta/proc/self/status para ver el uso de la memoria. ulimit -a mostró que la memoria virtual era ilimitada. Alguien también me sugirió que se pueden usar DDT y TotalView para verificar dónde se está consumiendo la memoria de códigos. – rks171

+0

TotalView tiene algunos recursos avanzados de depuración de memoria, pero no lo he usado extensamente. Al menos, cualquier depurador podría mostrarle dónde se produce el error de memoria. Al final podría ser algo diferente al agotamiento de la memoria. –

+0

Me pasó por la mente: ¿tus nodos de clúster no se intercambian? En caso afirmativo, es posible que esté agotando la memoria total del sistema y que el asesino de OOM de Linux esté funcionando ... –

Cuestiones relacionadas