是否可以使cuda使用在函数外声明的单线程范围变量(寄存器或本地内存)?
我的大多数设备功能都需要使用相同的变量。
我不想将与参数相同的变量传递给我的所有设备函数,而是想在函数外部声明变量。
这可能吗?
我的计算容量是1.2。
编辑:一个例子:
__device__ __local__ int id;
__device__ __local__ int variable1 = 3;
__device__ __local__ int variable2 = 5;
__device__ __local__ int variable3 = 8;
__device__ __local__ int variable4 = 8;
//
__device__ int deviceFunction3() {
variable1 += 8;
variable4 += 7;
variable2 += 1;
variable3 += id;
return variable1 + variable2 + variable3;
}
__device__ int deviceFunction2() {
variable3 += 8;
variable1 += deviceFunction3();
variable4 += deviceFunction3();
return variable3 + variable4;
}
__device__ int deviceFunction1() {
variable1 += id;
variable4 += 2;
variable2 += deviceFunction2();
variable3 += variable2 + variable4;
return variable1 + variable2 + variable3 + variable4;
}
// Kernel
__global__ void kernel(int *dev_a, int *dev_b, int *dev_c) {
id = get_id();
dev_c[id] = deviceFunction1();
}
3个设备功能需要操作相同的变量。每个变量都是依赖于每个线程计算的。根据我的理解,我不能使用上面的代码,因为我无法声明变量,因此它们是每个线程的本地代码。
我需要做的是在内核函数中声明所有变量,然后将指针传递给所有其他函数:
__device__ int deviceFunction3(int* id,int* variable1,int* variable2,int* variable3,int* variable4) {
*variable1 += 8;
*variable4 += 7;
*variable2 += 1;
*variable3 += 2;
return *variable1 + *variable2 + *variable3;
}
__device__ int deviceFunction2(int* id,int* variable1,int* variable2,int* variable3,int* variable4) {
*variable3 += 8;
*variable1 += deviceFunction3(id,variable1,variable2,variable3,variable4);
*variable4 += deviceFunction3(id,variable1,variable2,variable3,variable4);
return *variable3 + *variable4;
}
__device__ int deviceFunction1(int* id,int* variable1,int* variable2,int* variable3,int* variable4) {
*variable1 += *id;
*variable4 += 2;
*variable2 += deviceFunction2(id,variable1,variable2,variable3,variable4);
*variable3 += *variable2 + *variable4;
return *variable1 + *variable2 + *variable3 + *variable4;
}
// Kernel
__global__ void kernel(int *dev_a, int *dev_b, int *dev_c) {
int id = get_id();
int variable1 = 3;
int variable2 = 5;
int variable3 = 8;
int variable4 = 8;
dev_c[id] = deviceFunction1(&id,&variable1,&variable2,&variable3,&variable4);
}
答案 0 :(得分:3)
你的使用案例是一个非常糟糕的想法,我不会向我最大的敌人推荐这种设计模式。暂且不谈代码的优点,正如我在评论中暗示的那样,你可以通过在结构中封装它们所依赖的__device__函数和变量来实现你想要的线程局部变量作用域,如下所示:
struct folly
{
int id;
int variable1;
int variable2;
int variable3;
int variable4;
__device__ folly(int _id) {
id = _id;
variable1 = 3;
variable2 = 5;
variable3 = 8;
variable4 = 8;
}
__device__ int deviceFunction3() {
variable1 += 8;
variable4 += 7;
variable2 += 1;
variable3 += id;
return variable1 + variable2 + variable3;
}
__device__ int deviceFunction2() {
variable3 += 8;
variable1 += deviceFunction3();
variable4 += deviceFunction3();
return variable3 + variable4;
}
__device__ int deviceFunction1() {
variable1 += id;
variable4 += 2;
variable2 += deviceFunction2();
variable3 += variable2 + variable4;
return variable1 + variable2 + variable3 + variable4;
}
};
__global__ void kernel(int *dev_a, int *dev_b, int *dev_c) {
int id = threadIdx.x + blockIdx.x * blockDim.x;
folly do_calc(id);
dev_c[id] = do_calc.deviceFunction1();
}
另请注意,CUDA支持C ++样式通过引用传递,因此您在第二段代码中编写的任何一个设备函数都可以像这样编写:
__device__ int deviceFunction3(int & variable1, int & variable2,
int & variable3, int & variable4)
{
variable1 += 8;
variable4 += 7;
variable2 += 1;
variable3 += 2;
return variable1 + variable2 + variable3;
}
更清晰,更容易阅读。
答案 1 :(得分:-1)
我只想补充一点,我已经得出结论认为这是不可能的。我发现它是CUDA C的一个主要设计问题。
我在某些幻灯片中看到了一个名为__local__
的关键字,但我找不到任何文档,nvcc也无法识别它。
我想所有应该仅具有单个线程范围的变量必须仅在函数内声明。