Czy ktoś może opisać różnice między __global__
i __device__
?
Kiedy używać __device__
, a kiedy używać __global__
?
Czy ktoś może opisać różnice między __global__
i __device__
?
Kiedy używać __device__
, a kiedy używać __global__
?
Odpowiedzi:
Funkcje globalne są również nazywane „jądrem”. Są to funkcje, które możesz wywołać po stronie hosta za pomocą semantyki wywołań jądra CUDA ( <<<...>>>
).
Funkcje urządzenia można wywołać tylko z innego urządzenia lub funkcji globalnych. __device__
funkcje nie mogą być wywoływane z kodu hosta.
Różnice między funkcjami __device__
i __global__
to:
__device__
funkcje można wywołać tylko z urządzenia i są one wykonywane tylko w urządzeniu.
__global__
funkcje mogą być wywoływane z hosta i są wykonywane w urządzeniu.
Dlatego wywołujesz __device__
funkcje z funkcji jądra i nie musisz ustawiać ustawień jądra. Można również „przeciążenie” to funkcja, na przykład: można zadeklarować void foo(void)
i __device__ foo (void)
, a następnie jeden jest wykonywany na komputerze i może być wywołana tylko z funkcji gospodarza. Drugi jest wykonywany na urządzeniu i może być wywoływany tylko z urządzenia lub funkcji jądra.
Możesz również odwiedzić poniższy link: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , był dla mnie przydatny.
__global__
- Działa na GPU, wywoływanym z CPU lub GPU *. Wykonywane z <<<dim3>>>
argumentami.__device__
- Działa na GPU, wywoływanym z GPU. Może być również stosowany z variabiles.__host__
- Działa na procesorze, wywoływanym z procesora.*) __global__
funkcje można wywołać z innych __global__
funkcji, uruchamiając
możliwości obliczeniowe. 3.5.
Wyjaśnię to na przykładzie:
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
}
tj. gdy chcemy, aby funkcja hosta (CPU) wywoływała funkcję urządzenia (GPU), wówczas używana jest funkcja „ global ”. Przeczytaj to: „ https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialGlobalFunctions ”
A kiedy chcemy, aby funkcja urządzenia (GPU) (raczej jądro) wywoływała inną funkcję jądra, używamy „ urządzenia ”. Przeczytaj to „ https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions ”
To powinno wystarczyć, aby zrozumieć różnicę.
Na razie odnotowuję tu jakieś nieuzasadnione spekulacje (uzasadnię je później, gdy trafię na jakieś autorytatywne źródło) ...
__device__
funkcje mogą mieć zwracany typ inny niż void, ale __global__
funkcje muszą zawsze zwracać void.
__global__
funkcje mogą być wywoływane z innych jąder działających na GPU w celu uruchomienia dodatkowych wątków GPU (jako część dynamicznego modelu równoległości CUDA (inaczej CNP)), podczas gdy __device__
funkcje działają w tym samym wątku, co jądro wywołujące.
__global__
funkcja to definicja jądra. Za każdym razem, gdy jest wywoływany z procesora, jądro to jest uruchamiane na GPU.
Jednak każdy wątek wykonujący to jądro może wymagać wielokrotnego wykonywania kodu, na przykład zamiany dwóch liczb całkowitych. Zatem tutaj możemy napisać funkcję pomocniczą, tak jak robimy to w programie C. W przypadku wątków wykonywanych na GPU funkcję pomocniczą należy zadeklarować jako __device__
.
W ten sposób funkcja urządzenia jest wywoływana z wątków jądra - jedna instancja dla jednego wątku. Podczas gdy funkcja globalna jest wywoływana z wątku procesora.
__global__
to słowo kluczowe CUDA C (specyfikator deklaracji), które mówi, że funkcja,
funkcje globalne (jądra) uruchamiane przez kod hosta przy użyciu <<< no_of_blocks , no_of threads_per_block>>>
. Każdy wątek wykonuje jądro według swojego unikalnego identyfikatora wątku.
Jednak __device__
funkcji nie można wywoływać z kodu hosta. Jeśli musisz to zrobić, użyj obu __host__
__device__
.
Funkcja globalna może być wywoływana tylko z hosta i nie ma zwracanego typu, podczas gdy funkcja urządzenia może być wywoływana tylko z funkcji jądra innej funkcji urządzenia, dlatego nie wymaga ustawienia jądra
__global__
funkcje mogą być również wywoływane z urządzenia przy użyciu semantyki jądra CUDA (<<< ... >>>), jeśli używasz dynamicznego równoległości - co wymaga CUDA 5.0 i możliwości obliczeniowych 3.5 lub wyższych.