Разница между глобальными функциями и функциями устройства

110

Кто-нибудь может описать различия между __global__и __device__?

Когда я должен использовать __device__, а когда использовать __global__?

Мехди Саман Буй
источник

Ответы:

137

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

Функции устройства могут быть вызваны только из другого устройства или глобальных функций. __device__функции не могут быть вызваны из кода хоста.

Евгений
источник
14
Как дополнение, __global__функции также могут быть вызваны с устройства с использованием семантики ядра CUDA (<<< ... >>>), если вы используете динамический параллелизм - для этого требуется CUDA 5.0 и вычислительные возможности 3.5 или выше.
Tom
39

Различия между __device__и __global__функциями:

__device__ функции можно вызывать только с устройства, и это выполняется только на устройстве.

__global__ функции могут быть вызваны с хоста, и они выполняются на устройстве.

Следовательно, вы вызываете __device__функции из функций ядра, и вам не нужно устанавливать настройки ядра. Вы также можете «перегрузить» функцию, например: вы можете объявить void foo(void)и __device__ foo (void), затем одна выполняется на хосте и может быть вызвана только из функции хоста. Другой выполняется на устройстве и может быть вызван только из устройства или функции ядра.

Вы также можете перейти по следующей ссылке: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , мне это пригодилось.

ФакундоГФлорес
источник
32
  1. __global__- Работает на GPU, вызывается из CPU или GPU *. Выполнено <<<dim3>>>аргументировано.
  2. __device__- Работает на GPU, вызывается из GPU. Может использоваться и с вариабильными автомобилями.
  3. __host__ - Работает на ЦП, вызывается из ЦП.

*) __global__функции могут быть вызваны из других __global__функций, начиная с
вычислительных возможностей 3.5.

Грешану Эмануэль - Василе
источник
5
Это слишком поздно - он был правильным в то время, когда задавался вопрос, но он больше не является правильным с момента изобретения динамического параллелизма .
tera
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
}

т.е. когда мы хотим, чтобы функция хоста (ЦП) вызывала функцию устройства (ГП), используется « глобальный ». Прочтите это: " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialGlobalFunctions "

И когда мы хотим, чтобы функция устройства (графического процессора) (скорее, ядра) вызывала другую функцию ядра, мы используем « устройство ». Прочтите « https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions ».

Этого должно быть достаточно, чтобы понять разницу.

sandeep.ganage
источник
13

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

Perreal
источник
7

Я пока записываю здесь несколько необоснованных домыслов (я их обосновываю позже, когда найду какой-нибудь авторитетный источник) ...

  1. __device__функции могут иметь тип возврата, отличный от void, но __global__функции всегда должны возвращать void.

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

Самоучка
источник
7

__global__функция - это определение ядра. Каждый раз, когда он вызывается из CPU, это ядро ​​запускается на GPU.

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

Таким образом, функция устройства вызывается из потоков ядра - один экземпляр для одного потока. В то время как глобальная функция вызывается из потока ЦП.

Лорин Ахмед
источник
7

__global__ - ключевое слово CUDA C (спецификатор объявления), которое говорит, что функция,

  1. Выполняется на устройстве (GPU)
  2. Вызовы от кода хоста (ЦП).

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

Однако __device__функции не могут быть вызваны из кода хоста. Если вам нужно это сделать, используйте оба __host__ __device__.

Тилина Пиядасун
источник
2

Глобальная функция может быть вызвана только с хоста, и у них нет типа возврата, в то время как функция устройства может быть вызвана только из функции ядра другой функции устройства, поэтому не требует настройки ядра

Harishbisht29
источник