我正在使用CUDA 5.0。我注意到编译器允许我在内核中使用主机声明的 int 常量。但是,它拒绝编译使用主机声明的 float 常量的任何内核。有谁知道这种看似不一致的原因?
例如,下面的代码运行得很好,但是如果内核中的最后一行被取消注释,它将无法编译。
#include <cstdio>
#include <cuda_runtime.h>
static int __constant__ DEV_INT_CONSTANT = 1;
static float __constant__ DEV_FLOAT_CONSTANT = 2.0f;
static int const HST_INT_CONSTANT = 3;
static float const HST_FLOAT_CONSTANT = 4.0f;
__global__ void uselessKernel(float * val)
{
*val = 0.0f;
// Use device int and float constants
*val += DEV_INT_CONSTANT;
*val += DEV_FLOAT_CONSTANT;
// Use host int and float constants
*val += HST_INT_CONSTANT;
//*val += HST_FLOAT_CONSTANT; // won't compile if uncommented
}
int main(void)
{
float * d_val;
cudaMalloc((void **)&d_val, sizeof(float));
uselessKernel<<<1, 1>>>(d_val);
cudaFree(d_val);
}
答案 0 :(得分:4)
在设备代码中添加常数是正常的,但在设备代码中添加存储在主机内存中的数字不是。
当从未引用该变量的addr时,编译器/优化器可以用值static const int
替换代码中3
的每个引用。在这种情况下,它类似于#define HST_INT_CONSTANT 3
,并且没有为此变量分配主机内存。
但是对于float
var,主机内存总是被分配,即使它是static const float
。由于内核无法直接访问主机内存,因此不会编译static const float
的代码。
对于C / C ++,int
可以比float
更积极地进行优化。
当评论为ON时,您运行的代码可以被视为CUDA C的错误。 static const int
是主机端的东西,不应该直接访问设备。