Alguém pode descrever as diferenças entre __global__
e __device__
?
Quando devo usar __device__
e quando usar __global__
?
Alguém pode descrever as diferenças entre __global__
e __device__
?
Quando devo usar __device__
e quando usar __global__
?
Respostas:
As funções globais também são chamadas de "kernels". São as funções que você pode chamar do lado do host usando a semântica de chamada do kernel CUDA ( <<<...>>>
).
As funções do dispositivo só podem ser chamadas de outro dispositivo ou funções globais. __device__
funções não podem ser chamadas a partir do código do host.
As diferenças entre as funções __device__
e __global__
são:
__device__
as funções podem ser chamadas apenas a partir do dispositivo e são executadas apenas no dispositivo.
__global__
funções podem ser chamadas a partir do host e são executadas no dispositivo.
Portanto, você chama __device__
funções a partir de funções de kernel e não precisa definir as configurações do kernel. Você também pode "sobrecarregar" uma função, por exemplo: você pode declarar void foo(void)
e __device__ foo (void)
, então uma é executada no host e só pode ser chamada a partir de uma função de host. O outro é executado no dispositivo e só pode ser chamado de um dispositivo ou função do kernel.
Você também pode visitar o seguinte link: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , foi útil para mim.
__global__
- É executado na GPU, chamado a partir da CPU ou GPU *. Executado com <<<dim3>>>
argumentos.__device__
- É executado na GPU, chamado da GPU. Também pode ser usado com variáveis.__host__
- É executado na CPU, chamado a partir da CPU.*) __global__
funções podem ser chamadas de outras __global__
funções, iniciando a
capacidade de computação 3.5.
Vou explicar com um exemplo:
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
}
ou seja, quando queremos uma função de host (CPU) para chamar uma função de dispositivo (GPU), então ' global ' é usado. Leia isto: " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialGlobalFunctions "
E quando queremos uma função de dispositivo (GPU) (em vez de kernel) para chamar outra função de kernel, usamos ' dispositivo '. Leia este " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions "
Isso deve ser o suficiente para entender a diferença.
Estou registrando algumas especulações infundadas aqui por enquanto (irei substanciá-las mais tarde, quando encontrar alguma fonte confiável) ...
__device__
as funções podem ter um tipo de retorno diferente de void, mas as __global__
funções devem sempre retornar void.
__global__
funções podem ser chamadas de outros kernels em execução na GPU para lançar threads adicionais da GPU (como parte do modelo de paralelismo dinâmico CUDA (também conhecido como CNP)) enquanto as __device__
funções são executadas na mesma thread que o kernel de chamada.
__global__
função é a definição de kernel. Sempre que é chamado da CPU, esse kernel é iniciado na GPU.
No entanto, cada thread que executa esse kernel pode exigir a execução de algum código repetidamente, por exemplo, a troca de dois inteiros. Portanto, aqui podemos escrever uma função auxiliar, assim como fazemos em um programa C. E para threads em execução na GPU, uma função auxiliar deve ser declarada como __device__
.
Assim, uma função de dispositivo é chamada de threads de um kernel - uma instância para uma thread. Enquanto, uma função global é chamada de thread da CPU.
__global__
é uma palavra-chave CUDA C (especificador de declaração) que diz que a função,
funções globais (kernels) lançadas pelo código do host usando <<< no_of_blocks , no_of threads_per_block>>>
. Cada thread executa o kernel por seu id de thread exclusivo.
No entanto, as __device__
funções não podem ser chamadas do código do host. Se você precisar fazer isso, use ambos __host__
__device__
.
A função global só pode ser chamada a partir do host e não tem um tipo de retorno enquanto a função de dispositivo só pode ser chamada a partir de uma função de kernel de outra função de dispositivo, portanto, não requer configuração de kernel
__global__
funções também podem ser chamadas a partir do dispositivo usando a semântica do kernel CUDA (<<< ... >>>) se você estiver usando o paralelismo dinâmico - que requer CUDA 5.0 e capacidade de computação 3.5 ou superior.