Різниця між глобальною функцією та функцією пристрою


108

Чи може хтось описати відмінності між __global__та __device__?

Коли я повинен використовувати __device__і коли використовувати __global__?.

Відповіді:


136

Глобальні функції також називають «ядрами». Це функції, які можна зателефонувати з боку хоста за допомогою семантики виклику ядра CUDA ( <<<...>>>).

Функції пристрою можна викликати лише з інших пристроїв або глобальних функцій. __device__функції не можна викликати з коду хоста.


14
Як додаток, __global__функції можна також викликати з пристрою, використовуючи семантику ядра CUDA (<<< ... >>>), якщо ви використовуєте динамічний паралелізм - для цього потрібен CUDA 5.0 та можливість обчислення 3.5 або вище.
Том

39

Відмінності між __device__і __global__функціями:

__device__ функції можна викликати лише з пристрою, і він виконується лише в пристрої.

__global__ функції можна викликати з хоста, і він виконується в пристрої.

Отже, ви викликаєте __device__функції з функцій ядер, і вам не доведеться встановлювати настройки ядра. Ви також можете "перевантажити" функцію, наприклад: ви можете оголосити void foo(void)і __device__ foo (void), тоді одна виконується на хості і може бути викликана лише з функції хоста. Інший виконується на пристрої і може бути викликаний лише з функції пристрою або ядра.

Ви також можете відвідати таке посилання: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , мені це було корисно.


31
  1. __global__- працює на графічному процесорі, викликаному з процесора або GPU *. Виконується <<<dim3>>>аргументами.
  2. __device__- працює на GPU, дзвонив з GPU. Можна використовувати і з змінними.
  3. __host__ - працює на процесорі, викликаному з процесора.

*) __global__функції можна викликати з інших __global__функцій, починаючи
обчислювальну здатність 3.5.


5
Ця відповідь трохи пізно - вона була правильною на той момент, коли було задано питання, але вона не є правильною вже з часу створення динамічного паралелізму .
тера

16

Я поясню це на прикладі:

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
}

тобто коли ми хочемо, щоб функція хоста (CPU) викликала функцію пристрою (GPU), тоді використовується " global ". Читайте це: " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialGlobalFunctions "

І коли ми хочемо, щоб функція пристрою (GPU) (а не ядро) викликала іншу функцію ядра, ми використовуємо « пристрій ». Прочитайте це " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions "

Цього має бути достатньо, щоб зрозуміти різницю.


13

__global__призначений для ядер cuda, функцій, які можна дзвонити безпосередньо від хоста. __device__функції можна викликати з __global__і __device__функцій, але не від хоста.


7

На даний момент я записую деякі необгрунтовані міркування (я обґрунтую їх пізніше, коли натрапляю на якесь авторитетне джерело) ...

  1. __device__функції можуть мати тип повернення, відмінний від void, але __global__функції завжди повинні повертати void.

  2. __global__функції можна викликати всередині інших ядер, що працюють на GPU, щоб запустити додаткові потоки GPU (як частина моделі динамічного паралелізму CUDA (він же CNP)), а __device__функції виконуються в тому ж потоці, що і викликає ядро.


7

__global__функція - це визначення ядра. Кожного разу, коли воно викликається з процесора, це ядро ​​запускається в GPU.

Однак кожен потік, що виконує це ядро, може зажадати виконувати якийсь код знову і знову, наприклад, підміняючи два цілих числа. Таким чином, тут ми можемо написати функцію помічника, як ми робимо в програмі C. А для потоків, що виконуються на GPU, хелперна функція повинна бути оголошена як __device__.

Таким чином, функція пристрою викликається з потоків ядра - один екземпляр для одного потоку. Тоді як глобальна функція викликається з потоку процесора.


7

__global__ - це ключове слово CUDA C (специфікатор декларації), який говорить, що функція,

  1. Виконує на пристрої (GPU)
  2. Дзвінки з хосту (CPU) коду.

глобальні функції (ядра), запущені кодом хоста за допомогою <<< no_of_blocks , no_of threads_per_block>>>. Кожен потік виконує ядро ​​своїм унікальним ідентифікатором потоку.

Однак __device__функції не можна викликати з хостового коду. Якщо вам потрібно зробити це, використовуйте обидві __host__ __device__.


2

Глобальну функцію можна викликати тільки з хоста, і вони не мають типу повернення, тоді як функцію пристрою можна викликати лише з функції ядра інших функцій пристрою, отже, не потрібно налаштування ядра

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.