全局函数与设备函数的区别

152

有人能描述一下 __global____device__ 之间的区别吗?

何时应该使用 __device__,何时应该使用 __global__

9个回答

183

全局函数也被称为"内核"。它是您可以使用CUDA内核调用语义(<<<...>>>)从主机端调用的函数。

设备函数只能从其他设备或全局函数中调用。__device__函数不能从主机代码中调用。


21
附加说明:如果你正在使用动态并行性,__global__函数也可以使用CUDA内核语义(<<<...>>>)从设备上调用,这需要CUDA 5.0和计算能力3.5或更高。 - Tom

53
  1. __global__ - 运行在 GPU 上,可以从 CPU 或 GPU 调用*. 使用 <<<dim3>>> 参数执行。
  2. __device__ - 运行在 GPU 上, 可以从 GPU 调用. 也可用于变量。
  3. __host__ - 运行在 CPU 上, 只能从 CPU 调用。

*) 只有当计算能力达到 3.5 或以上时,__global__ 函数才能被其他 __global__ 函数调用。


7
这个回答有点晚了 - 在问题被提出时是正确的,但由于 动态并行 的发明,它现在不再正确。请注意,我已经尽力使翻译通俗易懂,但没有改变原意。 - tera

49

__device____global__ 函数的区别如下:

__device__ 函数只能从设备调用,且仅在设备上执行。

__global__ 函数可以从主机调用,但在设备上执行。

因此,您可以从内核函数中调用 __device__ 函数,并且不必设置内核设置。您还可以“重载”一个函数,例如:您可以声明 void foo(void)__device__ foo (void),其中一个在主机上执行并且只能从主机函数调用。另一个在设备上执行,并且只能从设备或内核函数调用。

您也可以访问以下链接:http://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions,这对我很有帮助。


19

我将通过一个例子来解释:

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)函数(即核函数)调用另一个核函数时,我们使用“device”。请阅读:https://code.google.com/p/stanford-cs193g-sp2010/wiki/TutorialDeviceFunctions

这应该足以理解它们之间的区别。


16

__global__ 是用于 CUDA kernel 的关键字,表示可以直接从主机上调用的函数。而 __device__ 函数可以被 __global____device__ 函数调用,但不能从主机上调用。


8

__global__函数是核心函数的定义。每当它从CPU调用时,该核心就会在GPU上启动。

但是,执行该核心的每个线程可能需要再次执行某些代码,例如交换两个整数。因此,在这里我们可以编写一个辅助函数,就像在C程序中一样。对于在GPU上执行的线程,应将辅助函数声明为__device__

因此,设备函数从核心的线程中调用-每个线程实例调用一次。而全局函数从CPU线程中调用。


7

我在这里记录一些无根据的猜测(当我找到一些权威来源时,我将对这些内容进行证实)...

  1. __device__函数可以返回void以外的类型,但是__global__函数必须始终返回void。

  2. __global__函数可以从GPU上运行的其他内核中调用,以启动附加的GPU线程(作为CUDA动态并行性模型(又名CNP)的一部分),而__device__函数在调用内核相同的线程上运行。


7

__global__ 是 CUDA C 的关键字(声明说明符),表示函数:

  1. 在设备(GPU)上执行
  2. 从主机(CPU)代码调用。

使用 <<< no_of_blocks , no_of threads_per_block>>> 从主机代码启动全局函数(内核)。每个线程通过其唯一的线程 ID 执行内核。

但是,__device__ 函数无法从主机代码中调用。如果需要这样做,请同时使用 __host____device__


2

全局函数只能从主机调用,它们没有返回类型;设备函数只能从其他设备函数或内核函数中调用,因此不需要内核设置。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接