Quelqu'un peut-il décrire les différences entre __global__
et __device__
?
Quand devrais-je utiliser __device__
, et quand utiliser __global__
?.
Les fonctions globales sont également appelées "noyaux". Ce sont les fonctions que vous pouvez appeler du côté de l’hôte à l’aide de la sémantique d’appel du noyau CUDA (<<<...>>>
).
Les fonctions de l'appareil ne peuvent être appelées qu'à partir d'autres fonctions de l'appareil ou globales. Les fonctions __device__
Ne peuvent pas être appelées à partir du code de l'hôte.
Les différences entre les fonctions __device__
Et __global__
Sont les suivantes:
Les fonctions __device__
Ne peuvent être appelées qu'à partir du périphérique et sont exécutées uniquement dans le périphérique.
Les fonctions __global__
Peuvent être appelées à partir de l'hôte et sont exécutées dans l'appareil.
Par conséquent, vous appelez les fonctions __device__
À partir des fonctions de noyau, sans avoir à 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 l'une d'entre elles est exécutée sur l'hôte et ne peut être appelée 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'une fonction de périphérique ou 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. Exécuté avec <<<dim3>>>
arguments.__device__
- Fonctionne sur le GPU, appelé depuis le GPU. Peut être utilisé avec les variabiles aussi.__Host__
- Fonctionne sur la CPU, appelée depuis la CPU.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), on utilise alors ' global '. Lisez ceci: " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialGlobalFunctions "
Et lorsque nous souhaitons qu'une fonction périphérique (GPU) (plutôt que le noyau) appelle une autre fonction du noyau, nous utilisons ' device '. Lisez ceci " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions "
Cela devrait être suffisant pour comprendre la différence.
__global__
est destiné aux noyaux cuda, fonctions appelables directement à partir de l'hôte. __device__
les fonctions peuvent être appelées de __global__
et __device__
fonctionne mais pas de l'hôte.
Je suis en train d'enregistrer des spéculations non fondées ici pour le moment (je les justifierai plus tard lorsque je rencontrerai une source faisant autorité) ...
Les fonctions __device__
Peuvent avoir un type de retour autre que void mais les fonctions __global__
Doivent toujours renvoyer void.
Les fonctions __global__
Peuvent être appelées à partir d'autres noyaux fonctionnant 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 fonctions __device__
S'exécutent sur le même thread que le noyau appelant.
__global__
Est un mot clé CUDA C (spécificateur de déclaration) qui indique que la fonction,
fonctions globales (noyaux) lancées par le code de l'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 fonctions __device__
Ne peuvent pas être appelées à partir du code hôte. Si vous devez le faire, utilisez les deux __Host__
__device__
.
__global__
fonction est la définition du noyau. Chaque fois qu’il est appelé depuis le processeur, ce noyau est lancé sur le GPU.
Cependant, chaque thread exécutant ce noyau peut nécessiter l'exécution répétée d'un code, par exemple l'échange de deux entiers. Ainsi, ici, nous pouvons écrire une fonction d’aide, comme dans un programme C. Et pour les threads s'exécutant sur GPU, une fonction d'assistance doit être déclarée en tant que __device__
.
Ainsi, une fonction de périphérique est appelée à partir des threads du noyau - une instance pour un thread. Pendant ce temps, une fonction globale est appelée à partir du thread de la CPU.
La fonction globale ne peut être appelée qu'à partir de l'hôte et ils n'ont pas de type de retour, alors que Device Function ne peut être appelée qu'à partir de la fonction du noyau d'une autre fonction de périphérique. Par conséquent, le paramétrage du noyau n'est pas nécessaire.