Подтвердить что ты не робот

Сокращение использования памяти в расширенной сессии Mathematica

Я занимаюсь довольно длинными вычислениями, которые могут легко охватывать несколько дней. В ходе этих вычислений иногда у Mathematica заканчивается память. Для этого я пришел к чему-то вроде:

ParallelEvaluate[$KernelID]; (* Force the kernels to launch *)
kernels = Kernels[];

Do[
   If[Mod[iteration, n] == 0,
      CloseKernels[kernels];
      LaunchKernels[kernels];
      ClearSystemCache[]];
   (* Complicated stuff here *)
   Export[...], (* If a computation ends early I don't want to lose past results *)
   {iteration, min, max}]

Это здорово и все, но со временем основное ядро ​​накапливает память. В настоящее время мое основное ядро ​​питается примерно 1,4 ГБ оперативной памяти. Есть ли способ заставить Mathematica очистить память, которую он использует? Я пробовал littering Share и Clear в течение многих Modules, которые я использую в своем коде, но память все еще, кажется, накапливается с течением времени.

Я также попытался удостовериться, что у меня нет ничего большого и сложного, выполняющегося за пределами Module, так что что-то не остается слишком длинным. Но даже при этом у меня все еще есть проблемы с памятью.

Есть ли что-нибудь, что я могу сделать по этому поводу? У меня всегда будет большой объем памяти, так как большинство моих вычислений связаны с несколькими большими и плотными матрицами (обычно 1200 x 1200, но это может быть больше), поэтому я с осторожностью отношусь к использованию MemoryConstrained.


Update:

Проблема была именно в том, что сказал Алексей Попков в своем ответе. Если вы используете Module, память со временем будет течь медленно. В этом случае это усугублялось, потому что у меня было несколько операторов Module[..]. "Основной" Module находился в пределах ParallelTable, где сразу выполнялось 8 ядер. Отметьте (относительно) большое количество итераций, и это стало питательной средой для лотов утечек памяти из-за ошибки с Module.

4b9b3361

Ответ 1

Поскольку вы широко используете Module, я думаю, вам может быть интересно узнать эту ошибку с не удалением временных переменных Module.

Пример (не удаляя несвязанные временные переменные с их определениями):

In[1]:= $HistoryLength=0;
a[b_]:=Module[{c,d},d:=9;d/;b===1];
[email protected][$Context<>"*"]

Out[3]= 6

In[4]:= lst=Table[a[1],{1000}];
[email protected][$Context<>"*"]

Out[5]= 1007

In[6]:= lst=.
[email protected][$Context<>"*"]

Out[7]= 1007

In[8]:= [email protected]$999

Out[8]= Attributes[d$999]={Temporary}

d$999:=9

Обратите внимание, что в приведенном выше коде я установил $HistoryLength = 0;, чтобы подчеркнуть это ошибочное поведение Module. Если вы этого не сделаете, временные переменные все еще могут быть связаны из переменных истории (In и Out) и не будут удалены с их определениями по этой причине в более широком наборе случаев (это не ошибка, но особенность, как упомянул Леонид).

ОБНОВЛЕНИЕ: Только для записи. Существует еще одна старая ошибка с не удалением неизменяемых переменных Module после Part назначений им в v.5.2, которая не полностью фиксирована даже в версии 7.0.1:

In[1]:= $HistoryLength=0;$Version
Module[{L=Array[0&,10^7]},L[[#]]++&/@Range[100];];
Names["L$*"]
[email protected]@#&/@Names["L$*"]
Out[1]= 7.0 for Microsoft Windows (32-bit) (February 18, 2009)
Out[3]= {L$111}
Out[4]= {40000084}

Ответ 2

Вы пытались оценить $HistoryLength=0; во всех подъядрах, а также в главном ядре? Отслеживание истории является наиболее распространенным источником для выхода из памяти.

Вы пытались не использовать медленный и потребляющий память Export и вместо этого использовать быстрый и эффективный Put?

Не понятно из вашего сообщения, где вы оцениваете ClearSystemCache[] - в главном ядре или в подъядрах? Похоже, вы оцениваете его только в главном ядре. Попытайтесь оценить его во всех субядрах перед каждой итерацией.