如果我们有 __host__ __device__ CUDA 中的函数,我们可以在其实现中使用宏为主机端和设备端代码选择不同的代码路径,如下所示:
__host__ __device__ int foo(int x)
{
#ifdef CUDA_ARCH
return x * 2;
#else
return x;
#endif
}
但是为什么我们不能写:
__host__ __device__ int foo(int x);
__device__ int foo(int x) { return x * 2; }
__host__ int foo(int x) { return x; }
相反?
请您参考如下方法:
CUDA C++ 的 Clang 实现实际上支持 __host__ 上的重载,并且 __device__ 因为它认为执行空间限定符是函数签名的一部分。但请注意,即使在那里,您也必须单独声明这两个函数:
__device__ int foo(int x);
__host__ int foo(int x);
__device__ int foo(int x) { return x * 2; }
__host__ int foo(int x) { return x; }
就我个人而言,我不确定这到底有多可取/有多重要。考虑一下,您可以在 CUDA 源外部的主机代码中定义一个 foo(int x) 。如果有人告诉我他们需要为主机和设备提供相同功能的不同实现,其中出于某种原因需要将主机版本定义为 CUDA 源的一部分,我最初的直觉是可能会发生一些事情一个奇怪的方向。如果主机版本做了不同的事情,那么它很可能不会有不同的名称吗?如果它在逻辑上做同样的事情只是不使用 GPU,那么为什么它必须是 CUDA 源的一部分?我通常主张尽可能保持主机和设备代码之间的干净和严格分离,并将 CUDA 源代码中的任何主机代码保持在最低限度。即使您不关心代码的整洁性,这样做至少也会最大限度地减少因幕后发生的所有编译器魔法而受到伤害的机会......
