【发布时间】:2013-05-01 05:55:09
【问题描述】:
有人知道如何使用 Cuda 检查代码是在 GPU 还是 CPU 上运行?
__device__ __host__ double count_something(double variable) {
if (RUN_ON_GPU) {
use_cuda_variables();
} else {
use_cpu_variables();
}
}
【问题讨论】:
有人知道如何使用 Cuda 检查代码是在 GPU 还是 CPU 上运行?
__device__ __host__ double count_something(double variable) {
if (RUN_ON_GPU) {
use_cuda_variables();
} else {
use_cpu_variables();
}
}
【问题讨论】:
没有办法runtime检查一段代码在哪个架构上运行,但也不需要知道,因为它可以在编译时确定并进行相应处理。 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 question 或 CUDA 编程指南的 C language extensions 部分阅读有关编译转向的更全面的讨论。
【讨论】:
__CUDA_ARCH__ 甚至可以在主机代码中定义,但在这种情况下它被定义为 0。因此正确的检查是这样的:__device__ __host__ float function(float x) { #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0)) return 10.0f * __sinf(x); #else // host code here #endif }
#if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0)) 绝对是正确答案。
我无法在 cmets 中添加正确的代码降价 - 决定添加完整答案。
仅使用 __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
}
【讨论】: