2016-02-13 17 views
7

Sono molto confuso da quanto riportato da numpy.ndarray.nbytes.Perché questa matrice numerica gigante (non sparsa) si adatta alla RAM

Ho appena creato una matrice di identità di dimensione 1 milione (10^6), che pertanto ha 1 trilione di righe (10^12). Numpy riporta che questo array è 7,28 TB, eppure il processo Python utilizza solo 3,98 GB di memoria, come riportato dal monitor di attività OSX.

  • L'intero array è contenuto nella memoria?
  • Numpy comprime in qualche modo la sua rappresentazione o è gestita dal sistema operativo?
  • Se si calcola semplicemente y = 2 * x, che dovrebbe essere della stessa dimensione di x, la memoria di processo aumenta a circa 30 GB, fino a quando non viene uccisa dal sistema operativo. Perché, e che tipo di operazioni posso condurre su x senza che l'utilizzo della memoria si espanda così tanto?

Questo è il codice che ho usato:

import numpy as np 
x = np.identity(1e6) 
x.size 
# 1000000000000 
x.nbytes/1024 ** 4 
# 7.275957614183426 
y = 2 * x 
# python console exits and terminal shows: Killed: 9 
+0

Su Windows né la versione a 32 bit né a 64 bit mi ha permesso di allocare una matrice così grande –

+2

La mia ipotesi è che sia correlata a [questo] (http://stackoverflow.com/q/27574881/1461210), sebbene io sia un po 'sorpreso dal fatto che funzioni per matrici di identità anziché solo zeri. –

+0

@TamasHegedus cosa succede se crei una matrice di identità di dimensione '2e4'? Dovrebbero essere necessari 2,98 GB di RAM. Il processo occupa così tanta RAM? – Rems

risposta

5

Su Linux (e sto assumendo la stessa cosa accade in Mac), quando un programma alloca la memoria, il sistema operativo in realtà non si alloca finché non lo usa.

Se il programma non utilizza mai la memoria, il sistema operativo non deve sprecare RAM su di esso, ma mette il sistema operativo in un punto quando il programma richiede una tonnellata di memoria e in realtà ha bisogno di usarlo, ma il sistema operativo non ha abbastanza.

Quando ciò accade, il sistema operativo può iniziare a uccidere altri processi minori e fornire la propria RAM al processo di richiesta, o semplicemente eliminare il processo di richiesta (che è ciò che sta accadendo ora).

I 4 GB iniziali di memoria utilizzati da Python sono probabilmente le pagine in cui numpy ha impostato 1 nella matrice identità; il resto delle pagine non è ancora stato utilizzato. Facendo un'operazione matematica come inizia l'accesso (e quindi lo spostamento) di tutte le pagine fino a quando il sistema operativo esaurisce la memoria e uccide il processo.

1

Il sistema assegna solo memoria virtuale, solo la prima volta che si scrive su questa memoria, viene effettivamente utilizzato fisicamente. Per il tuo esempio, assegni 1 trilione di numeri che corrispondono a 2 miliardi di pagine di memoria, ma solo 1 milione (1e6) di queste pagine sono usate per scrivere quelle sulla diagonale. Sono esattamente i 4 GB di memoria che vedi.

Problemi correlati