Kann jemand die Unterschiede zwischen __global__
und beschreiben __device__
?
Wann soll ich verwenden __device__
und wann __global__
?
Kann jemand die Unterschiede zwischen __global__
und beschreiben __device__
?
Wann soll ich verwenden __device__
und wann __global__
?
Antworten:
Globale Funktionen werden auch als "Kernel" bezeichnet. Dies sind die Funktionen, die Sie von der Hostseite aus mithilfe der CUDA-Kernelaufrufsemantik ( <<<...>>>
) aufrufen können .
Gerätefunktionen können nur von anderen Geräte- oder globalen Funktionen aufgerufen werden. __device__
Funktionen können nicht über den Hostcode aufgerufen werden.
Unterschiede zwischen __device__
und __global__
Funktionen sind:
__device__
Funktionen können nur vom Gerät aus aufgerufen werden und werden nur im Gerät ausgeführt.
__global__
Funktionen können vom Host aus aufgerufen werden und werden im Gerät ausgeführt.
Daher rufen Sie __device__
Funktionen von Kernelfunktionen auf und müssen die Kerneleinstellungen nicht festlegen. Sie können eine Funktion auch "überladen", z. B.: Sie können deklarieren void foo(void)
und __device__ foo (void)
dann wird eine auf dem Host ausgeführt und kann nur von einer Host-Funktion aufgerufen werden. Der andere wird auf dem Gerät ausgeführt und kann nur von einem Gerät oder einer Kernelfunktion aufgerufen werden.
Sie können auch den folgenden Link besuchen: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , es war nützlich für mich.
__global__
- Läuft auf der GPU, die von der CPU oder der GPU * aufgerufen wird. Mit <<<dim3>>>
Argumenten ausgeführt.__device__
- Läuft auf der GPU, die von der GPU aufgerufen wird. Kann auch mit Variablen verwendet werden.__host__
- Läuft auf der CPU, die von der CPU aufgerufen wird.*) __global__
Funktionen können von anderen __global__
Funktionen aus aufgerufen werden, die die
Rechenfähigkeit 3.5 starten .
Ich werde es mit einem Beispiel erklären:
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
}
Wenn also eine Hostfunktion (CPU) eine Gerätefunktion (GPU) aufrufen soll, wird ' global ' verwendet. Lesen Sie dies: " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialGlobalFunctions "
Und wenn eine Gerätefunktion (GPU) (eher ein Kernel) eine andere Kernelfunktion aufrufen soll, verwenden wir ' Gerät '. Lesen Sie diese " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions "
Dies sollte ausreichen, um den Unterschied zu verstehen.
Ich nehme hier vorerst einige unbegründete Spekulationen auf (ich werde diese später begründen, wenn ich auf eine maßgebliche Quelle stoße) ...
__device__
Funktionen können einen anderen Rückgabetyp als void haben, aber __global__
Funktionen müssen immer void zurückgeben.
__global__
Funktionen können aus anderen Kerneln heraus aufgerufen werden, die auf der GPU ausgeführt werden, um zusätzliche GPU-Threads (als Teil des dynamischen Parallelitätsmodells von CUDA (auch bekannt als CNP)) zu starten, während __device__
Funktionen auf demselben Thread wie der aufrufende Kernel ausgeführt werden.
__global__
Funktion ist die Definition des Kernels. Immer wenn es von der CPU aufgerufen wird, wird dieser Kernel auf der GPU gestartet.
Jeder Thread, der diesen Kernel ausführt, muss jedoch möglicherweise immer wieder Code ausführen, z. B. zwei Ganzzahlen austauschen. Somit können wir hier eine Hilfsfunktion schreiben, genau wie wir es in einem C-Programm tun. Und für Threads, die auf einer GPU ausgeführt werden, sollte eine Hilfsfunktion als deklariert werden __device__
.
Daher wird eine Gerätefunktion von Threads eines Kernels aufgerufen - eine Instanz für einen Thread. Währenddessen wird eine globale Funktion vom CPU-Thread aufgerufen.
__global__
ist ein CUDA C-Schlüsselwort (Deklarationsspezifizierer), das besagt, dass die Funktion,
globale Funktionen (Kernel), die vom Host-Code mit gestartet werden <<< no_of_blocks , no_of threads_per_block>>>
. Jeder Thread führt den Kernel anhand seiner eindeutigen Thread-ID aus.
Allerdings __device__
können Funktionen nicht vom Host aufgerufen werden code.if Sie tun müssen , um sie beide verwenden __host__
__device__
.
Die globale Funktion kann nur vom Host aufgerufen werden und hat keinen Rückgabetyp, während die Gerätefunktion nur von der Kernelfunktion einer anderen Gerätefunktion aufgerufen werden kann und daher keine Kerneleinstellung erforderlich ist
__global__
Funktionen auch mithilfe der CUDA-Kernelsemantik (<<< ... >>>) vom Gerät aus aufgerufen werden, wenn Sie dynamische Parallelität verwenden - dies erfordert CUDA 5.0 und Rechenfähigkeit 3.5 oder höher.