2010-08-05 3 views
21

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

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

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

ответ

12

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

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

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

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

4

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

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

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

2

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

+0

@Alexy, вы можете указать на пример кода/демо? –

+0

@myaccount_ram Пример: http://stackoverflow.com/a/5017071/590388 –

7

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

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

+0

В 7.0.1 Я получаю сообщение об ошибке: '' Необязательно :: opdef: Значение по умолчанию для необязательного аргумента BoxForm 'pat _: {_, __ } содержит шаблон. >> '', но я также получаю вывод. Вы тоже получаете ошибку? –

+0

@ Mr.Wizard В новой сессии я их не получаю, но после некоторой работы вышеприведенный код начинает создавать эти сообщения. –

Смежные вопросы