全局函数和设备函数之间的差异

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

什么时候应该使用 __device__,什么时候应该使用 __global__

89439 次浏览

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

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

__global__用于 Cuda 内核,这些函数可以直接从主机调用。可以从 __global____device__函数调用 __device__函数,但不能从主机调用。

__device____global__功能的区别是:

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

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

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

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

我将用一个例子来解释:

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)函数时,就会使用‘ 全球性的

当我们需要一个设备(GPU)函数(相当于内核)调用另一个内核函数时,我们使用‘ 装置

这应该足以理解其中的区别。

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

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

因此,从内核的线程调用设备函数——一个实例对应一个线程。而从 CPU 线程调用全局函数。

我正在记录一些毫无根据的猜测在这里暂时(我将证实这些以后当我遇到一些权威的来源) ..。

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

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

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

__global__是一个 CUDA C 关键字(声明说明符) ,它表示函数,

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

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

但是,如果需要同时使用 __host__ __device__调用,则不能从主机 code.0调用 __device__函数。

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

*)可以从其他 __global__函数开始调用 __global__函数
计算能力3.5。