Qualcuno può descrivere le differenze tra __global__
e __device__
?
Quando dovrei usare __device__
e quando usarlo __global__
?.
Qualcuno può descrivere le differenze tra __global__
e __device__
?
Quando dovrei usare __device__
e quando usarlo __global__
?.
Risposte:
Le funzioni globali sono anche chiamate "kernel". Sono le funzioni che puoi chiamare dal lato host usando semantics ( <<<...>>>
) della chiamata del kernel CUDA .
Le funzioni del dispositivo possono essere chiamate solo da altri dispositivi o funzioni globali. __device__
le funzioni non possono essere chiamate dal codice host.
Le differenze tra __device__
e le __global__
funzioni sono:
__device__
le funzioni possono essere chiamate solo dal dispositivo e vengono eseguite solo nel dispositivo.
__global__
le funzioni possono essere chiamate dall'host e vengono eseguite nel dispositivo.
Pertanto, chiamate le __device__
funzioni dalle funzioni del kernel e non dovete impostare le impostazioni del kernel. Puoi anche "sovraccaricare" una funzione, ad esempio: puoi dichiarare void foo(void)
e __device__ foo (void)
, quindi una viene eseguita sull'host e può essere chiamata solo da una funzione host. L'altro viene eseguito sul dispositivo e può essere chiamato solo da un dispositivo o da una funzione del kernel.
Puoi anche visitare il seguente link: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , è stato utile per me.
__global__
- Funziona sulla GPU, chiamata dalla CPU o dalla GPU *. Eseguito con <<<dim3>>>
argomenti.__device__
- Funziona sulla GPU, chiamata dalla GPU. Può essere utilizzato anche con variabili.__host__
- Funziona sulla CPU, chiamata dalla CPU.*) le __global__
funzioni possono essere chiamate da altre __global__
funzioni a partire dalla
capacità di calcolo 3.5.
Lo spiegherò con un esempio:
main()
{
// Your main function. Executed by CPU
}
__global__ void calledFromCpuForGPU(...)
{
//This function is called by CPU and suppose to be executed on GPU
}
__device__ void calledFromGPUforGPU(...)
{
// This function is called by GPU and suppose to be executed on GPU
}
cioè, quando vogliamo che una funzione host (CPU) chiami una funzione dispositivo (GPU), viene utilizzato " globale ". Leggi questo: " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialGlobalFunctions "
E quando vogliamo che una funzione del dispositivo (GPU) (piuttosto che il kernel) chiami un'altra funzione del kernel, usiamo " dispositivo ". Leggi questo " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions "
Questo dovrebbe essere sufficiente per capire la differenza.
Sto registrando alcune speculazioni infondate qui per il momento (le confermerò più tardi quando mi imbatterò in una fonte autorevole) ...
__device__
le funzioni possono avere un tipo di ritorno diverso da void ma le __global__
funzioni devono sempre restituire void.
__global__
le funzioni possono essere chiamate dall'interno di altri kernel in esecuzione sulla GPU per avviare thread GPU aggiuntivi (come parte del modello di parallelismo dinamico CUDA (noto anche come CNP)) mentre le __device__
funzioni vengono eseguite sullo stesso thread del kernel chiamante.
__global__
funzione è la definizione di kernel. Ogni volta che viene chiamato dalla CPU, quel kernel viene avviato sulla GPU.
Tuttavia, ogni thread che esegue quel kernel, potrebbe richiedere di eseguire del codice ancora e ancora, ad esempio lo scambio di due numeri interi. Quindi, qui possiamo scrivere una funzione di supporto, proprio come facciamo in un programma C. E per i thread in esecuzione su GPU, una funzione di supporto dovrebbe essere dichiarata come __device__
.
Pertanto, una funzione dispositivo viene chiamata dai thread di un kernel: un'istanza per un thread. Mentre, una funzione globale viene chiamata dal thread della CPU.
__global__
è una parola chiave CUDA C (specificatore di dichiarazione) che dice che la funzione,
funzioni globali (kernel) avviate dal codice host utilizzando <<< no_of_blocks , no_of threads_per_block>>>
. Ogni thread esegue il kernel in base al suo ID thread univoco.
Tuttavia, le __device__
funzioni non possono essere chiamate dal codice host. Se è necessario, utilizzare entrambe __host__
__device__
.
La funzione globale può essere chiamata solo dall'host e non hanno un tipo di ritorno mentre la funzione dispositivo può essere chiamata solo dalla funzione kernel di un'altra funzione dispositivo quindi non richiede l'impostazione del kernel
__global__
funzioni possono anche essere chiamate dal dispositivo usando la semantica del kernel CUDA (<<< ... >>>) se stai usando il parallelismo dinamico - che richiede CUDA 5.0 e capacità di calcolo 3.5 o superiore.