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

Использование памяти профилирования в Mathematica

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

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

EDIT: я только что узнал о функции ByteCount (которая показывает некоторые тревожные результаты по базовым типам данных, но это помимо точки), но даже сумма по всем моим переменным нигде не приближается к сумме, принятой математическим выражением. Что дает?

4b9b3361

Ответ 1

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

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

Вы также можете посмотреть функции MaxMemoryUsed и MemoryInUse.

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

Ответ 2

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

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

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

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

screenshot

Ответ 3

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

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

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

Ответ 4

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