Différence entre les fonctions globales et les fonctions de périphérique

Quelqu’un peut-il décrire les différences entre __global__ et __device__ ?

Quand dois-je utiliser __device__ et quand utiliser __global__ ?.

Les fonctions globales sont également appelées “kernelx”. Ce sont les fonctions que vous pouvez appeler depuis l’hôte en utilisant la sémantique des appels du kernel CUDA ( <<<...>>> ).

Les fonctions de l’appareil ne peuvent être appelées qu’à partir d’autres fonctions de l’appareil ou globales. __device__ fonctions __device__ ne peuvent pas être appelées à partir du code hôte.

Les différences entre les fonctions __device__ et __global__ sont les suivantes:

__device__ fonctions __device__ ne peuvent être appelées qu’à partir de l’appareil et elles ne sont exécutées que dans l’appareil.

__global__ fonctions __global__ peuvent être appelées depuis l’hôte et exécutées dans l’appareil.

Par conséquent, vous appelez les fonctions __device__ partir des fonctions de kernelx et vous n’avez pas à définir les parameters du kernel. Vous pouvez également “surcharger” une fonction, par exemple: vous pouvez déclarer void foo(void) et __device__ foo (void) , alors l’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 kernel.

Vous pouvez également visiter le lien suivant: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , il m’a été utile.

  1. __global__ – Fonctionne sur le GPU, appelé depuis le CPU. Exécuté avec les arguments <<>> .
  2. __device__ – Fonctionne sur le GPU, appelé depuis le GPU. Peut être utilisé avec des variabiles aussi.
  3. __host__ – Fonctionne sur le processeur, appelé depuis le 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), 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 un kernel) appelle une autre fonction du kernel, nous utilisons ” device “. Lisez ceci ” https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions

Cela devrait suffire à comprendre la différence.

__global__ est pour les kernelx cuda, fonctions qui peuvent être appelées directement par l’hôte. __device__ fonctions __device__ peuvent être appelées depuis les fonctions __global__ et __device__ mais pas depuis l’hôte.

J’enregistre des spéculations non fondées ici pour le moment (je les corroborerai plus tard quand je trouverai une source faisant autorité) …

  1. __device__ fonctions __device__ peuvent avoir un type de retour autre que void mais les fonctions __global__ doivent toujours renvoyer void.

  2. __global__ fonctions __global__ peuvent être appelées depuis d’autres kernelx fonctionnant sur le GPU pour lancer des threads GPU supplémentaires (dans le cadre du modèle de parallélisme dynamic CUDA (aka CNP)) tandis __device__ fonctions __device__ s’exécutent sur le même thread que le kernel appelant.

__golbal__ est un mot-clé CUDA C (spécificateur de déclaration) qui indique que la fonction,

  1. Exécute sur le périphérique (GPU)
  2. Appels à partir du code hôte (CPU).

fonctions globales (kernelx) lancées par le code hôte en utilisant <<< no_of_blocks, no_of threads_per_block >>>. Chaque thread exécute le kernel par son identifiant de thread unique.

Mais les fonctions __device__ ne peuvent pas être appelées à partir du code hôte.si vous avez besoin de le faire, utilisez les deux __host__ __device__

__global__ fonction __global__ est la définition du kernel. Chaque fois qu’il est appelé depuis le CPU, ce kernel est lancé sur le GPU.

Cependant, chaque thread exécutant ce kernel peut avoir besoin d’exécuter du code encore et encore, par exemple en échangeant deux entiers. Ainsi, nous pouvons écrire une fonction d’assistance, comme nous le faisons dans un programme en 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 d’un kernel – une instance pour un thread. Pendant ce temps, une fonction globale est appelée depuis le thread CPU.

La fonction globale ne peut être appelée qu’à partir de l’hôte et elle n’a pas de type de retour, alors que la fonction périphérique ne peut être appelée qu’à partir de la fonction kernel de la fonction autre périphérique.