2010-08-05 25 views
21

Esiste un modo per profilare l'utilizzo della memoria mathkernel (fino a singole variabili) diverso dal pagamento di $ $ per il proprio plug-in Eclipse (mathematica workbench, iirc)?Utilizzo della memoria di profilatura in Mathematica

In questo momento ho terminato l'esecuzione di un programma che richiede più GB di RAM, ma le uniche cose che vengono memorizzate dovrebbero essere al massimo ~ 50 MB di dati, eppure mathkernel.exe tende a trattenere ~ 1.5 GB (in pratica, come tanto quanto Windows lo darà). C'è un modo migliore per aggirare questo, oltre a salvare i dati di cui ho bisogno e lasciare il kernel ogni volta?

EDIT: Ho appena saputo della funzione ByteCount (che mostra alcuni risultati preoccupanti su tipi di dati di base, ma questo è oltre il punto), ma anche la somma su tutte le mie variabili non è neanche lontanamente la quantità presa da MathKernel. Cosa dà?

risposta

12

Una cosa che molti utenti non si rendono conto è che ci vuole memoria per memorizzare tutti gli ingressi e le uscite nei simboli In e Out, indipendentemente dal fatto che si assegni o meno un'uscita a una variabile. Out è anche con alias come %, dove % è l'output precedente, %% è il penultimo, ecc. %123 equivale a Out[123].

Se non avete l'abitudine di usare %, o si utilizza solo per un paio di livelli di profondità, impostare $HistoryLength-0 o un piccolo numero intero positivo, per mantenere solo l'ultima pochi (o nessun) uscite in giro in Out .

Si potrebbe anche voler guardare le funzioni MaxMemoryUsed e MemoryInUse.

Ovviamente, il problema $HistoryLength può essere o meno il tuo problema, ma non hai condiviso quale sia la tua valutazione effettiva. Se riesci a pubblicarlo, forse qualcuno sarà in grado di far luce sul motivo per cui è così intensivo di memoria.

4

Michael Pilat's answer è una buona soluzione e MemoryInUse e MaxMemoryUsed sono probabilmente i migliori strumenti disponibili. ByteCount raramente è molto utile perché ciò che misura può essere un enorme sovrastima perché ignora le sottoespressioni condivise e spesso ignora la memoria che non è direttamente accessibile attraverso le funzioni di Mathematica, che è spesso un componente importante dell'utilizzo della memoria.

Una cosa che è possibile fare in alcune circostanze è utilizzare la funzione Share, che forza le sottoespressioni da condividere quando possibile. In alcune circostanze, questo può far risparmiare decine o addirittura centinaia di magabyte. Puoi capire come funziona usando MemoryInUse prima e dopo aver usato Share.

Inoltre, alcune cose apparentemente innocue possono far sì che Mathematica utilizzi molto più memoria di quanto ci si aspetti. Le matrici contigue di macchine reali (e solo macchine reali) possono essere allocate come i cosiddetti array "compressi", in modo molto simile a C o Fortran. Tuttavia, se si dispone di un insieme di real machine e altre strutture (inclusi i simboli) in un array, tutto deve essere "boxed" e l'array diventa un array di puntatori, che può aggiungere un sovraccarico.

2

Un modo è quello di automatizzare il riavvio del kernel quando si esaurisce la memoria. È possibile eseguire il codice che consuma memoria in un kernel slave mentre il kernel master prende solo il risultato del calcolo e controlla l'utilizzo della memoria.

+0

@Alexy, si può puntare a un esempio di codice/demo? –

+0

@myaccount_ram Esempio: http://stackoverflow.com/a/5017071/590388 –

7

Ecco la mia soluzione per la profilazione di utilizzo della memoria:

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[R[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]] 

di valutazione della dà sopra la seguente tabella:

screenshot

+0

Su 7.0.1 viene visualizzato l'errore: '' Opzionale :: opdef: il valore predefinito per l'argomento facoltativo BoxForm'pat _: {_, __ } contiene un modello. >> '' ma ho anche l'output. Hai anche tu l'errore? –

+0

@ Mr.Wizard Nella sessione nuova non li capisco, ma dopo un po 'di lavoro il codice sopra riportato inizia a produrre questi messaggi. –