Кто-нибудь может описать различия между __global__
и __device__
?
Когда я должен использовать __device__
, а когда использовать __global__
?
Кто-нибудь может описать различия между __global__
и __device__
?
Когда я должен использовать __device__
, а когда использовать __global__
?
Ответы:
Глобальные функции также называются «ядрами». Это функции, которые вы можете вызывать со стороны хоста, используя семантику вызова ядра CUDA ( <<<...>>>
).
Функции устройства могут быть вызваны только из другого устройства или глобальных функций. __device__
функции не могут быть вызваны из кода хоста.
Различия между __device__
и __global__
функциями:
__device__
функции можно вызывать только с устройства, и это выполняется только на устройстве.
__global__
функции могут быть вызваны с хоста, и они выполняются на устройстве.
Следовательно, вы вызываете __device__
функции из функций ядра, и вам не нужно устанавливать настройки ядра. Вы также можете «перегрузить» функцию, например: вы можете объявить void foo(void)
и __device__ foo (void)
, затем одна выполняется на хосте и может быть вызвана только из функции хоста. Другой выполняется на устройстве и может быть вызван только из устройства или функции ядра.
Вы также можете перейти по следующей ссылке: http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions , мне это пригодилось.
__global__
- Работает на GPU, вызывается из CPU или 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
}
т.е. когда мы хотим, чтобы функция хоста (ЦП) вызывала функцию устройства (ГП), используется « глобальный ». Прочтите это: " https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialGlobalFunctions "
И когда мы хотим, чтобы функция устройства (графического процессора) (скорее, ядра) вызывала другую функцию ядра, мы используем « устройство ». Прочтите « https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions ».
Этого должно быть достаточно, чтобы понять разницу.
Я пока записываю здесь несколько необоснованных домыслов (я их обосновываю позже, когда найду какой-нибудь авторитетный источник) ...
__device__
функции могут иметь тип возврата, отличный от void, но __global__
функции всегда должны возвращать void.
__global__
функции могут быть вызваны из других ядер, работающих на графическом процессоре, для запуска дополнительных потоков графического процессора (как часть модели динамического параллелизма CUDA (также известной как CNP)), в то время как __device__
функции выполняются в том же потоке, что и вызывающее ядро.
__global__
функция - это определение ядра. Каждый раз, когда он вызывается из CPU, это ядро запускается на 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 или выше.