2012-07-24 1 views
11

Stavo profilando il mio programma Cuda 4 e ho scoperto che a un certo punto il processo in esecuzione usava oltre 80 GiB di memoria virtuale. Era molto più di quanto mi sarei aspettato. Dopo aver esaminato l'evoluzione della mappa di memoria nel tempo e confrontando ciò riga di codice è in esecuzione si è scoperto che dopo queste semplici istruzioni utilizzo della memoria virtuale urtato fino a oltre 80 GB:Perché il runtime di Cuda riserva la memoria virtuale di 80 GiB al momento dell'inizializzazione?

int deviceCount; 
    cudaGetDeviceCount(&deviceCount); 
    if (deviceCount == 0) { 
    perror("No devices supporting CUDA"); 
    } 

Chiaramente, questo è la prima chiamata CUDA, quindi il runtime è stato inizializzato. Dopo questo la mappa di memoria assomiglia (troncato):

Address   Kbytes  RSS Dirty Mode Mapping 
0000000000400000 89796 14716  0 r-x-- prg 
0000000005db1000  12  12  8 rw--- prg 
0000000005db4000  80  76  76 rw--- [ anon ] 
0000000007343000 39192 37492 37492 rw--- [ anon ] 
0000000200000000 4608  0  0 ----- [ anon ] 
0000000200480000 1536 1536 1536 rw--- [ anon ] 
0000000200600000 83879936  0  0 ----- [ anon ] 

Ora, con questo enorme area di memoria mappata nello spazio di memoria virtuale.

Ok, forse non è un grosso problema dal momento che riservare/allocare memoria in Linux non fa molto se non si scrive effettivamente su questa memoria. Ma è davvero fastidioso dal momento che ad esempio i lavori MPI devono essere specificati con la quantità massima di vmem utilizzabile dal lavoro. E 80GiB è solo un limite inferiore per i lavori di Cuda: bisogna aggiungere anche tutte le altre cose.

Posso immaginare che abbia a che fare con il cosiddetto scratch space che sostiene Cuda. Una sorta di pool di memoria per il codice del kernel che può crescere e ridursi dinamicamente. Ma questa è speculazione. Inoltre è allocato nella memoria del dispositivo.

Eventuali approfondimenti?

risposta

12

Niente a che fare con lo spazio di lavoro, è il risultato del sistema di indirizzamento che consente l'accesso unificato e peer-to-peer tra host e più GPU. Il driver CUDA registra tutta la memoria della GPU (s) + la memoria host in un singolo spazio di indirizzamento virtuale usando il sistema di memoria virtuale del kernel. Non è in realtà il consumo di memoria, di per sé, è solo un "trucco" per mappare tutti gli spazi di indirizzi disponibili in uno spazio virtuale lineare per l'indirizzamento unificato.

+0

Ok, ha senso. Quindi, nel mio caso l'host ha 48 GB di RAM installati + 8 GB di swap e 4 GPU con 6 GB ciascuno in totale 80 GB. Bingo! Questo significa che se alloco su un heap normale, questo apparirebbe anche all'interno di questi 80 GB? – ritter

+0

Heap è solo un'allocazione da ciascuna memoria GPU per ogni contesto. Non vedrai un cambiamento nella memoria virtuale a causa dell'heap, ma la memoria libera che l'API segnala su una data GPU diminuirà. – talonmies

+7

@Frank: Posso avere il tuo computer? :) –