programming - nvidia cuda




Memoria appuntata predefinita contro memoria a copia zero (2)

In CUDA possiamo usare la memoria bloccata per copiare in modo più efficiente i dati da Host a GPU rispetto alla memoria predefinita allocata tramite malloc all'host. Tuttavia, esistono due tipi di memorie bloccate, la memoria bloccata predefinita e la memoria bloccata a zero copie .

La memoria bloccata predefinita copia i dati da Host a GPU due volte più veloci dei normali trasferimenti, quindi c'è sicuramente un vantaggio (a condizione che abbiamo abbastanza memoria host per bloccare la pagina)

Nella diversa versione della memoria bloccata, ovvero la memoria a zero copia , non è necessario copiare completamente i dati dall'host alla DRAM della GPU. I kernel leggono i dati direttamente dalla memoria dell'Host.

La mia domanda è: quale di questi tipi di memoria bloccata è una pratica di programmazione migliore.


La memoria pinned mappata è identica ad altri tipi di memoria bloccata sotto tutti gli aspetti, tranne per il fatto che è mappata nello spazio degli indirizzi CUDA, quindi può essere letta e scritta dai kernel CUDA e utilizzata per i trasferimenti DMA dai Copy Engine.

Il vantaggio di non mappare la memoria bloccata era duplice: ti ha permesso di risparmiare spazio di indirizzamento, che può essere un bene prezioso in un mondo di piattaforme a 32 bit con GPU che possono contenere 3-4G di RAM. Inoltre, la memoria che non è mappata non può essere accidentalmente corrotta dai kernel rogue. Ma questa preoccupazione è abbastanza esoterica che la funzionalità di spazio di indirizzo unificata in CUDA 4.0 farà sì che tutte le assegnazioni a pin siano mappate per impostazione predefinita.

Oltre ai punti sollevati dal libro Sanders / Kandrot, altre cose da tenere a mente:

  • scrivere su host di memoria da un kernel (ad esempio per pubblicare i risultati sulla CPU) è bello in quanto la GPU non ha alcuna latenza da coprire in quel caso, e

  • È MOLTO IMPORTANTE che le operazioni di memoria siano coalizzate, altrimenti anche le GP 2.x e successive generano un grande successo di larghezza di banda.


Penso che dipenda dalla tua applicazione (altrimenti, perché dovrebbero fornire entrambi i modi?)

La memoria mappata e bloccata (copia zero) è utile quando:

  • La GPU non ha memoria da sola e utilizza comunque la RAM

  • Carichi i dati esattamente una volta, ma hai un sacco di calcoli da eseguire su di esso e vuoi nascondere le latenze di trasferimento della memoria attraverso di essa.

  • Il lato host vuole cambiare / aggiungere più dati, o leggere i risultati, mentre il kernel è ancora in esecuzione (es. Comunicazione)

  • I dati non si adattano alla memoria della GPU

Si noti che, è anche possibile utilizzare più flussi per copiare dati ed eseguire kernel in parallelo.

La memoria fissata, ma non mappata è migliore:

  • Quando carichi o memorizzi i dati più volte. Ad esempio: hai più kernel successivi, eseguendo il lavoro in fasi: non è necessario caricare i dati dall'host ogni volta.

  • Non c'è molto calcolo da eseguire e le latenze di caricamento non verranno nascoste bene