检查代码是否在GPU或CPU上运行

7

有人知道如何使用Cuda检查代码是在GPU还是CPU上运行吗?

__device__ __host__  double count_something(double variable) {
  if (RUN_ON_GPU) {
    use_cuda_variables();
  } else {
    use_cpu_variables();
  }
}
2个回答

14

无法在运行时检查代码所运行的架构,但也不需要知道,因为可以在编译时确定并相应处理。 nvcc 定义了几个预处理符号,可用于在代码编译时解析编译轨迹。其中关键符号是 __CUDA_ARCH__,在编译主机代码时从未定义,在编译设备代码时始终定义。

因此,可以编写以下函数:

__device__ __host__ float function(float x)
{
#ifdef __CUDA_ARCH__
    return 10.0f * __sinf(x);
#else
    return 10.0f * sin(x);
#endif
}

该代码会根据编译对象是GPU还是主机而发出不同的代码。您可以在Stack Overflow问题或CUDA编程指南的C语言扩展部分中阅读有关编译转向的更详细讨论。


这不是完全正确的。在某些情况下,这段代码无法工作 - 我在找到解决方案之前花了很多时间进行调试。 - avtomaton
@avtomaton:什么不正确?在实际上只是C++预处理器代码的情况下,调试如何适应其中? - talonmies
2
这不是完全正确的。在某些情况下,这段代码无法正常工作 - 我花了很多时间进行调试,才找到解决方案。 __CUDA_ARCH__ 可以在主机代码中定义,但在这种情况下被定义为 0。 因此,适当的检查应该像这样: __device__ __host__ float function(float x) { #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0)) return 10.0f * __sinf(x); #else // 在此处编写主机代码 #endif } - avtomaton
#if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0)) 绝对是正确的答案。 - Pedro Boechat

5

我无法在评论中添加正确的代码标记-决定提供完整的答案。仅使用__CUDA_ARCH__定义检查并不完全正确。在某些情况下,此代码不起作用-在找到解决方案之前,我花费了很多时间进行调试(CUDA文档现在没有任何提及)。
即使在主机代码中,也可以定义__CUDA_ARCH__,但在这种情况下,它被定义为0。 因此,正确的检查应该像这样:

__device__ __host__ float function(float x)
{
#if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
    // device code here
    return 10.0f * __sinf(x);
#else
    // host code here
    return 10.0f * sin(x);
#endif
}

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