Чи може хтось описати відмінності між __global__
та __device__
?
Коли я повинен використовувати __device__
і коли використовувати __global__
?.
Чи може хтось описати відмінності між __global__
та __device__
?
Коли я повинен використовувати __device__
і коли використовувати __global__
?.
Відповіді:
Відмінності між __device__
і __global__
функціями:
__device__
функції можна викликати лише з пристрою, і він виконується лише в пристрої.
__global__
функції можна викликати з хоста, і він виконується в пристрої.
Отже, ви викликаєте __device__
функції з функцій ядер, і вам не доведеться встановлювати настройки ядра. Ви також можете "перевантажити" функцію, наприклад: ви можете оголосити void foo(void)
і __device__ foo (void)
, тоді одна виконується на хості і може бути викликана лише з функції хоста. Інший виконується на пристрої і може бути викликаний лише з функції пристрою або ядра.
Ви також можете відвідати таке посилання: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , мені це було корисно.
__global__
- працює на графічному процесорі, викликаному з процесора або GPU *. Виконується <<<dim3>>>
аргументами.__device__
- працює на GPU, дзвонив з GPU. Можна використовувати і з змінними.__host__
- працює на процесорі, викликаному з процесора.*) __global__
функції можна викликати з інших __global__
функцій, починаючи
обчислювальну здатність 3.5.
Я поясню це на прикладі:
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 "
Цього має бути достатньо, щоб зрозуміти різницю.
__global__
призначений для ядер cuda, функцій, які можна дзвонити безпосередньо від хоста. __device__
функції можна викликати з __global__
і __device__
функцій, але не від хоста.
На даний момент я записую деякі необгрунтовані міркування (я обґрунтую їх пізніше, коли натрапляю на якесь авторитетне джерело) ...
__device__
функції можуть мати тип повернення, відмінний від void, але __global__
функції завжди повинні повертати void.
__global__
функції можна викликати всередині інших ядер, що працюють на GPU, щоб запустити додаткові потоки GPU (як частина моделі динамічного паралелізму CUDA (він же CNP)), а __device__
функції виконуються в тому ж потоці, що і викликає ядро.
__global__
функція - це визначення ядра. Кожного разу, коли воно викликається з процесора, це ядро запускається в GPU.
Однак кожен потік, що виконує це ядро, може зажадати виконувати якийсь код знову і знову, наприклад, підміняючи два цілих числа. Таким чином, тут ми можемо написати функцію помічника, як ми робимо в програмі C. А для потоків, що виконуються на GPU, хелперна функція повинна бути оголошена як __device__
.
Таким чином, функція пристрою викликається з потоків ядра - один екземпляр для одного потоку. Тоді як глобальна функція викликається з потоку процесора.
__global__
- це ключове слово CUDA C (специфікатор декларації), який говорить, що функція,
глобальні функції (ядра), запущені кодом хоста за допомогою <<< no_of_blocks , no_of threads_per_block>>>
. Кожен потік виконує ядро своїм унікальним ідентифікатором потоку.
Однак __device__
функції не можна викликати з хостового коду. Якщо вам потрібно зробити це, використовуйте обидві __host__
__device__
.
Глобальну функцію можна викликати тільки з хоста, і вони не мають типу повернення, тоді як функцію пристрою можна викликати лише з функції ядра інших функцій пристрою, отже, не потрібно налаштування ядра
__global__
функції можна також викликати з пристрою, використовуючи семантику ядра CUDA (<<< ... >>>), якщо ви використовуєте динамічний паралелізм - для цього потрібен CUDA 5.0 та можливість обчислення 3.5 або вище.