2012-09-17 19 views
5

ho:Migliore o lo stesso: memcpy CPU() vs cudaMemcpy dispositivo() su appuntato, mappata la memoria in CUDA?

    memoria
  • Host che è stato bloccato e mappati utilizzando cudaHostAlloc(..., cudaHostAllocMapped) o cudaHostRegister(..., cudaHostRegisterMapped) con successo;
  • puntatori ai dispositivi sono stati ottenuti utilizzando cudaHostGetDevicePointer(...).

ho iniziato cudaMemcpy(..., cudaMemcpyDeviceToDevice) su puntatori src e dest dispositivo che puntano a due differenti regioni di memoria mappata bloccato + ottenuti con la tecnica di cui sopra. Tutto funziona bene.

Domanda: devo continuare a fare questo o semplicemente utilizzare uno stile CPU tradizionale memcpy() poiché tutto è comunque nella memoria di sistema? ... o sono il stessa (cioè fa cudaMemcpy mappa per una scala memcpy quando entrambi src e dest sono riposte)?

(sto ancora utilizzando il metodo cudaMemcpy perché in precedenza tutto era in memoria globale del dispositivo, ma da allora sono passati a memoria appuntato a causa di vincoli di dimensione GMEM)

+1

E 'una domanda interessante. A condizione che si utilizza un memcpy ottimizzato, la CPU è probabilmente meglio - la memoria appartiene ad esso, dopo tutto - e la capacità di una GPU discreta per fare host-> memcpy host è limitato a larghezza di banda PCIe. Ma se la GPU sarebbe inattiva altrimenti, perché no? – ArchaeaSoftware

+0

Spero che la GPU non stia facendo la copia. Spero che il runtime veda che i puntatori sono entrambi puntatori host e invocano una memcpy host. Ho chiesto di scoprire cosa succede realmente. – harrism

risposta

3

Con cudaMemcpy il driver CUDA rileva che si sta copiando da un puntatore host a un puntatore host e che la copia viene eseguita sulla CPU. Ovviamente puoi usare memcpy sulla CPU se preferisci.

Se si utilizza cudaMemcpy, ci può essere un flusso supplementare di sincronizzazione eseguito prima di fare la copia (che si può vedere nel profiler, ma credo ci — prova e vedere).

Su un sistema UVA si può semplicemente utilizzare cudaMemcpyDefault come talonmies dice nella sua risposta. Ma se non si dispone di UVA (sm_20 + e 64-bit OS), quindi è necessario chiamare la copia a destra (ad esempio cudaMemcpyDeviceToDevice). Se cudaHostRegister() tutto quello che ti interessa poi cudaMemcpyDeviceToDevice si finisce per fare quanto segue in base a dove si trova la memoria:

  • Host < -> Host: eseguita dalla CPU (memcpy)
  • Host < - > dispositivo: DMA (motore di copia del dispositivo)
  • dispositivo < -> dispositivo: kernel CUDA memcpy (corre sul SMS, lanciato dal pilota)
+0

molto interessante, hai qualche fonte in cui hai trovato le informazioni? –

+0

Credo di aver chiesto ai miei colleghi NVIDIA i dettagli di implementazione. – harrism

2

Se si sta lavorando su una piattaforma con UVA (unificata indirizzamento virtuale), suggerirei caldamente di utilizzare cudaMemcpy con cudaMemcpyDefault. In questo modo tutto ciò che riguarda il percorso più veloce diventa un dettaglio di implementazione dell'API interno di cui non devi preoccuparti.

+0

Sì e no, lavoro spesso su un C1060, ma ho accesso a C2050/70. Quindi, per quanto riguarda la mia domanda di memoria bloccata in particolare - sai cosa cudaMemcpyDefault fa dietro le quinte in questo caso?Ciò risponderebbe alla domanda più o meno. – schmichael

+0

Non lavoro. Per NVIDIA non ho visto alcun codice, ma sembra guardare i puntatori sorgente e destinazione e di conseguenza. Otterrai una copia lato host con un puntatore host e una copia da dispositivo a dispositivo con un puntatore del dispositivo – talonmies

Problemi correlati