Quelqu'un peut-il décrire les différences entre __global__
et __device__
?
Quand dois-je utiliser __device__
et quand utiliser __global__
?.
Quelqu'un peut-il décrire les différences entre __global__
et __device__
?
Quand dois-je utiliser __device__
et quand utiliser __global__
?.
Réponses:
Les fonctions globales sont également appelées "noyaux". Ce sont les fonctions que vous pouvez appeler du côté hôte en utilisant la sémantique des appels du noyau CUDA (<<<...>>>
).
Les fonctions de l'appareil ne peuvent être appelées qu'à partir d'un autre appareil ou de fonctions globales. __device__
les fonctions ne peuvent pas être appelées à partir du code hôte.
Les différences entre les fonctions __device__
et les __global__
fonctions sont les suivantes:
__device__
Les fonctions ne peuvent être appelées qu'à partir de l'appareil et ne sont exécutées que dans l'appareil.
__global__
Les fonctions peuvent être appelées à partir de l'hôte et exécutées dans le périphérique.
Par conséquent, vous appelez des __device__
fonctions à partir des fonctions du noyau et vous n'avez pas besoin de définir les paramètres du noyau. Vous pouvez également "surcharger" une fonction, par exemple: vous pouvez déclarer void foo(void)
et __device__ foo (void)
, puis un est exécuté sur l'hôte et ne peut être appelé qu'à partir d'une fonction hôte. L'autre est exécuté sur le périphérique et ne peut être appelé qu'à partir d'un périphérique ou d'une fonction du noyau.
Vous pouvez également visiter le lien suivant: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , cela m'a été utile.
__global__
- Fonctionne sur le GPU, appelé depuis le CPU ou le GPU *. Exécuté avec des <<<dim3>>>
arguments.__device__
- Fonctionne sur le GPU, appelé depuis le GPU. Peut également être utilisé avec des variabiles.__host__
- Fonctionne sur le CPU, appelé depuis le CPU.*) Les __global__
fonctions peuvent être appelées à partir d'autres __global__
fonctions à partir de la
capacité de calcul 3.5.
Je vais l'expliquer avec un exemple:
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
}
c'est-à-dire que lorsque nous voulons qu'une fonction hôte (CPU) appelle une fonction de périphérique (GPU), alors « global » est utilisé. Lisez ceci: " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialGlobalFunctions "
Et quand nous voulons qu'une fonction de périphérique (GPU) (plutôt que le noyau) appelle une autre fonction du noyau, nous utilisons « périphérique ». Lisez ceci " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions "
Cela devrait suffire à comprendre la différence.
J'enregistre ici des spéculations non fondées pour le moment (je les étayerai plus tard lorsque je trouverai une source faisant autorité) ...
__device__
Les fonctions peuvent avoir un type de retour autre que void mais les __global__
fonctions doivent toujours renvoyer void.
__global__
Les fonctions peuvent être appelées à partir d'autres noyaux exécutés sur le GPU pour lancer des threads GPU supplémentaires (dans le cadre du modèle de parallélisme dynamique CUDA (aka CNP)) tandis que les __device__
fonctions s'exécutent sur le même thread que le noyau appelant.
__global__
function est la définition du noyau. Chaque fois qu'il est appelé depuis le CPU, ce noyau est lancé sur le GPU.
Cependant, chaque thread exécutant ce noyau peut nécessiter d'exécuter du code encore et encore, par exemple l'échange de deux entiers. Ainsi, ici, nous pouvons écrire une fonction d'assistance, comme nous le faisons dans un programme C. Et pour les threads s'exécutant sur GPU, une fonction d'assistance doit être déclarée comme __device__
.
Ainsi, une fonction de périphérique est appelée à partir des threads d'un noyau - une instance pour un thread. Alors qu'une fonction globale est appelée à partir du thread CPU.
__global__
est un mot clé CUDA C (spécificateur de déclaration) qui dit que la fonction,
fonctions globales (noyaux) lancées par le code hôte en utilisant <<< no_of_blocks , no_of threads_per_block>>>
. Chaque thread exécute le noyau par son identifiant de thread unique.
Cependant, les __device__
fonctions ne peuvent pas être appelées à partir du code hôte. Si vous devez le faire, utilisez les deux __host__
__device__
.
La fonction globale ne peut être appelée qu'à partir de l'hôte et ils n'ont pas de type de retour tandis que la fonction de périphérique ne peut être appelée qu'à partir de la fonction du noyau d'une autre fonction de périphérique, donc ne nécessite pas de réglage du noyau
__global__
fonctions peuvent également être appelées depuis le périphérique en utilisant la sémantique du noyau CUDA (<<< ... >>>) si vous utilisez le parallélisme dynamique - cela nécessite CUDA 5.0 et la capacité de calcul 3.5 ou supérieure.