memory-management memory-leaks wolfram-mathematica

memory management - Mathematica se queda sin memoria



memory-management memory-leaks (1)

Auch, esta es una desagradable.

Lo que está sucediendo es que N hará el almacenamiento en caché de los resultados para acelerar los cálculos futuros si los necesita de nuevo. A veces esto es absolutamente lo que quieres, pero a veces simplemente rompe el mundo. Afortunadamente, tienes algunas opciones. Una es usar el comando ClearSystemCache , que hace exactamente lo que dijo en la lata. Después de que ejecuté su bucle sin paralelismo por un tiempo (antes de aburrirme y abortar el cálculo), MemoryInUse informó ~ 160 MiB en uso. El uso de ClearSystemCache lo redujo a unos 14 MiB.

Una cosa que debería considerar hacer, en lugar de llamar a ClearSystemCache programación, es usar SetSystemOptions para cambiar el comportamiento del almacenamiento en caché. Debería echar un vistazo a SystemOptions["CacheOptions"] para ver cuáles son las posibilidades.

EDIT: no es muy sorprendente que el almacenamiento en caché cause un problema mayor para expresiones más complejas. Tiene que estar escondiendo copias de esas expresiones en algún lugar, y las expresiones más complejas requieren más memoria.

Estoy intentando ejecutar el siguiente programa, que calcula las raíces de los polinomios de grado hasta d con coeficientes solo +1 o -1, y luego los almacena en archivos.

d = 20; n = 18000; f[z_, i_] := Sum[(2 Mod[Floor[(i - 1)/2^k], 2] - 1) z^(d - k), {k, 0, d}];

Aquí f [z, i] da un polinomio en z con signos más o menos que cuentan en binario. Digamos d = 2, tendríamos

f [z, 1] = -z 2 - z - 1
f [z, 2] = -z 2 - z + 1
f [z, 3] = -z 2 + z - 1
f [z, 4] = -z 2 + z + 1

DistributeDefinitions[d, n, f] ParallelDo[ Do[ root = N[Root[f[z, i], j]]; {a, b} = Round[n ({Re[root], Im[root]}/1.5 + 1)/2]; {i, 1, 2^d}], {j, 1, d}]

Me doy cuenta de que leer esto probablemente no sea muy agradable, pero de todos modos es relativamente corto. Habría tratado de reducir las partes relevantes, pero aquí realmente no tengo ni idea de cuál es el problema. Estoy calculando todas las raíces de f [z, i], y luego las redondeo para hacerlas corresponder a un punto en una cuadrícula by n, y guardar esos datos en varios archivos.

Por alguna razón, el uso de la memoria en Mathematica aumenta hasta llenar toda la memoria (6 GB en esta máquina); entonces el cálculo continúa extremadamente lento; ¿Por qué es esto?

No estoy seguro de qué está gastando la memoria aquí; mi única suposición era la cantidad de archivos que usaban la memoria, pero ese no es el caso: intenté agregar datos a archivos de 2GB y no hubo un uso notable de memoria para eso. Parece que no hay absolutamente ninguna razón para que Mathematica use grandes cantidades de memoria aquí.

Para valores pequeños de d (15 por ejemplo), el comportamiento es el siguiente: Tengo 4 núcleos en ejecución. A medida que todos se ejecutan a través del bucle ParallelDo (cada uno haciendo un valor de j a la vez), el uso de la memoria aumenta, hasta que todos terminan de pasar por ese bucle una vez. Luego, las siguientes veces que pasan por ese bucle, el uso de la memoria no aumenta en absoluto. El cálculo finalmente termina y todo está bien.

Además, lo que es bastante importante, una vez que el cálculo se detiene, el uso de la memoria no vuelve a disminuir. Si empiezo otro cálculo, sucede lo siguiente:

-Si el cálculo anterior se detuvo cuando el uso de la memoria seguía aumentando, continuaría aumentando (podría llevar un tiempo comenzar a aumentar nuevamente, básicamente para llegar al mismo punto en el cálculo).

-Si el cálculo anterior se detuvo cuando el uso de la memoria no aumentaba, no aumentaría más.

Edición: el problema parece provenir de la relativa complejidad de f: cambiarlo a un polinomio más fácil parece solucionar el problema. Pensé que el problema podría ser que Mathematica recuerda f [z, i] para valores específicos de i, pero configurando f [z, i]: =. Justo después de calcular una raíz de f [z, i] se queja de que la asignación no existía en primer lugar, y la memoria todavía se utiliza.

Realmente es bastante desconcertante, ya que f es lo único que me queda de memoria, pero definir f en el bucle interno Do y borrarlo cada vez que se calcula una raíz no resuelve el problema.