Профилирование использования памяти в Mathematica - PullRequest
21 голосов
/ 06 августа 2010

Есть ли способ профилировать использование памяти mathkernel (вплоть до отдельных переменных), кроме оплаты $$$ за их плагин Eclipse (mathematica workbench, iirc)?

Сейчас я заканчиваю выполнение программыэто занимает несколько ГБ оперативной памяти, но единственное, что хранится, должно быть не более ~ 50 МБ данных, но mathkernel.exe имеет тенденцию удерживать ~ 1,5 ГБ (в основном, столько, сколько Windows даст).Есть ли лучший способ обойти это, кроме сохранения необходимых мне данных и выхода из ядра каждый раз?

РЕДАКТИРОВАТЬ: я только что узнал о функции ByteCount (которая показывает некоторые тревожные результаты на основных типах данных, но это не главное), но даже сумма по всем моим переменным далеко не равна сумме, взятой mathkernel.Что дает?

Ответы [ 4 ]

12 голосов
/ 06 августа 2010

Многие пользователи не осознают, что для хранения всех ваших входов и выходов в символах In и Out требуется память, независимо от назначаете ли вы вывод переменной. Out также называется псевдонимом %, где % - предыдущий вывод, %% - второй по последнему слову и т. Д. %123 эквивалентен Out[123].

Если у вас нет привычки использовать % или использовать ее только на нескольких уровнях, установите $HistoryLength на 0 или небольшое положительное целое число, чтобы оставить только последний несколько (или нет) выходов в Out.

Возможно, вы также захотите взглянуть на функции MaxMemoryUsed и MemoryInUse.

Конечно, проблема $HistoryLength может быть или не быть вашей проблемой, но вы не поделились своей реальной оценкой. Если вы сможете опубликовать его, возможно, кто-то сможет пролить больше света на то, почему он так интенсивно использует память.

7 голосов
/ 17 августа 2011

Вот мое решение для профилирования использования памяти:

myByteCount[symbolName_String] := 
  Replace[ToHeldExpression[symbolName], 
   Hold[x__] :> 
    If[MemberQ[Attributes[x], Protected | ReadProtected], 
     Sequence @@ {}, {ByteCount[
       Through[{OwnValues, DownValues, UpValues, SubValues, 
          DefaultValues, FormatValues, NValues}[Unevaluated@x, 
         Sort -> False]]], symbolName}]];

With[{listing = myByteCount /@ Names[]},
 Labeled[Grid[Reverse@Take[Sort[listing], -100], Frame -> True, 
   Alignment -> Left], 
  Column[{Style[
     "ByteCount for symbols without attributes Protected and \
ReadProtected in all contexts", 16, FontFamily -> "Times"], 
    Style[Row@{"Total: ", Total[listing[[All, 1]]], " bytes for ", 
       Length[listing], " symbols"}, Bold]}, Center, 1.5], Top]]

Оценка выше дает следующую таблицу:

screenshot

4 голосов
/ 06 августа 2010

Ответ Михаила Пилата хороший, а MemoryInUse и MaxMemoryUsed, вероятно, лучшие инструменты, которые у вас есть. ByteCount редко бывает настолько полезен, потому что измеряемая величина может быть слишком завышенной, поскольку она игнорирует общие подвыражения и часто игнорирует память, которая не доступна напрямую через функции Mathematica, что часто является основным компонентом использования памяти.

Одна вещь, которую вы можете сделать при некоторых обстоятельствах, это использовать функцию Share, которая заставляет подвыражения делиться, когда это возможно. В некоторых случаях это может сэкономить десятки или даже сотни мегабайт. Вы можете сказать, насколько хорошо он работает, используя MemoryInUse до и после использования Share.

Кроме того, некоторые безобидные вещи могут заставить Mathematica использовать намного больше памяти, чем вы ожидаете. Смежные массивы машинных реалов (и только машинных реалов) могут быть выделены как так называемые «упакованные» массивы, во многом так же, как они были бы распределены C или Fortran. Тем не менее, если в массиве есть сочетание машинных чисел и других структур (включая символы), все должно быть «в штучной упаковке» , и массив становится массивом указателей, которые могут добавить много накладные расходы.

2 голосов
/ 15 февраля 2011

Один из способов - автоматизировать перезапуск ядра, когда ему не хватает памяти.Вы можете выполнить ваш код, потребляющий память, в подчиненном ядре, в то время как главное ядро ​​принимает только результаты вычислений и контролирует использование памяти.

...