我是cuda的新手,所以我希望我的问题不完全偏离基础。 我想在全局设备内存上创建一个数组,但我只知道它在主函数中间的大小(但在我访问设备之前)。
因为我不知道我在代码之前无法声明的大小: 设备 myArr []
所以我想在main,d_myArr中创建一个指针,然后使用cudaMalloc(d_myArr,arrSize)在设备上分配内存,但后来我从未在设备上声明变量。
我没有看到将d_Arr发送到我的内核的原因,因为它只会存在于该内核中(我认为?),我只是希望变量首先作为全局变量存在于我的设备上,并且可由不同的内核访问。
我可以在main中声明一个设备变量吗?如:
int main(){
.
.
__device__ myArr[size];
.
.
}
如果是这样的话,由于某些原因(由于我无法找到任何人这样做)而被废弃。如果这不允许我可以做什么呢?我看到有人提到cudaMemcpyToSymbol,但是我无法弄清楚它是否与我想要的完全相关,如果是的话我会很高兴如果有人能够解释它是如何用来实现我需要的。
在一个侧面问题上,我还有一个常量变量,我想在我的设备和主机上存在。现在我只声明了两次,一次使用设备,一次没有,有更好的方法吗?
答案 0 :(得分:2)
这不起作用。
__device__
变量必须在 global 范围内声明。__device__
变量关联的分配大小。相反,只要知道所需的分配大小,就可以使用cudaMalloc
为变量分配空间。此方法允许动态分配全局变量。 __device__
方法仅允许静态分配的全局变量。
这样的事情:
int main(){
// ...
int *d_data;
cudaMalloc(&d_data, size*sizeof(int));
// ...
kernel1<<<...>>>(d_data,...);
// ...
kernel2<<<...>>>(d_data,...);
// ...
}
如上所示,将这样一个动态分配的全局变量传递给多个内核是完全合法的,并且上面kernel1
放置的数据或修改(如果有的话)将对代码可见我在上面的kernel2
中运行,就我已经展示的例子而言。
对于常量变量问题,您提到的方法是合理的。如果您有这样的常量数据在编译时是未知的,那么这是一种明智的方法(您可能还希望使用__constant__
而不是__device__
进行调查)。另一方面,如果在编译时有 已知的常量数据,则使用
#define MYCONSTANT 123
或
constant int myconstant=123;
在全局范围内(即main
之外)将允许在主机或设备代码中同等使用此类定义,而无需声明或管理它两次。最后一种方法适用于POD数据类型(例如int
,float
,double
等),但不适用于struct
等复杂类型。