函数执行空间限定符用于指定函数是在主机上执行还是在设备上执行,以及是否可以从主机或设备调用。
7.1.1. global
__global__执行空间说明符将函数声明为内核。此类函数具有以下特性:
-
在设备上执行,
-
可从主机调用,
-
对于计算能力5.0或更高的设备可从设备端调用。
一个 __global__ 函数必须具有 void 返回类型,并且不能是类的成员。
任何对__global__函数的调用都必须按照执行配置中所述指定其执行配置。
调用__global__函数是异步的,这意味着它在设备完成执行之前就会返回。
7.1.2. device
__device__执行空间说明符用于声明一个函数,该函数具有以下特性:
-
在设备上执行,
-
仅可从设备端调用。
__global__ 和 __device__ 执行空间说明符不能同时使用。
7.1.3. host
__host__执行空间说明符声明了一个函数,该函数是:
-
在主机上执行,
-
仅可从主机端调用。
这相当于声明一个仅带有__host__执行空间说明符的函数,或者声明一个不包含任何__host__、__device__或__global__执行空间说明符的函数;无论哪种情况,该函数都仅为主机编译。
__global__ 和 __host__ 执行空间说明符不能同时使用。
__device__ 和 __host__ 执行空间说明符可以同时使用,在这种情况下,函数会同时为主机和设备编译。 应用兼容性中介绍的 __CUDA_ARCH__ 宏可用于区分主机和设备之间的代码路径:
__host__ __device__ func()
{
#if __CUDA_ARCH__ >= 800
// Device code path for compute capability 8.x
#elif __CUDA_ARCH__ >= 700
// Device code path for compute capability 7.x
#elif __CUDA_ARCH__ >= 600
// Device code path for compute capability 6.x
#elif __CUDA_ARCH__ >= 500
// Device code path for compute capability 5.x
#elif !defined(__CUDA_ARCH__)
// Host code path
#endif
}
7.1.4. 未定义行为
当出现以下情况时,"跨执行空间"调用具有未定义行为:
-
__CUDA_ARCH__已定义的情况下,从__global__、__device__或__host__ __device__函数内部调用__host__函数。 -
__CUDA_ARCH__未定义,从__host__函数内部调用__device__函数的情况。
7.1.5. noinline 和 forceinline
编译器会在认为适当时内联任何__device__函数。
__noinline__ 函数限定符可用作提示编译器尽可能不要内联该函数。
__forceinline__ 函数限定符可用于强制编译器内联该函数。
__noinline__ 和 __forceinline__ 函数限定符不能同时使用,且这两个限定符都不能应用于内联函数。
7.1.6. inline_hint
__inline_hint__限定符使编译器能够进行更激进的函数内联优化。与__forceinline__不同,它并不强制要求函数必须内联。在使用LTO(链接时优化)时,该限定符可用于提升跨模块的内联优化效果。
__noinline__ 和 __forceinline__ 函数限定符都不能与 __inline_hint__ 函数限定符一起使用。