Class 将struct作为参数传递给CUDA内核的行为
我对CUDA编程比较陌生,所以我想澄清在将结构传递到内核时结构的行为。我定义了以下Class 将struct作为参数传递给CUDA内核的行为,class,struct,cuda,Class,Struct,Cuda,我对CUDA编程比较陌生,所以我想澄清在将结构传递到内核时结构的行为。我定义了以下struct,在某种程度上模拟了知道自身大小的3D阵列的行为: struct protoarray { size_t dim1; size_t dim2; size_t dim3; float* data; }; 我创建了两个类型为protoarray的变量,在主机和设备端通过malloc和cudamaloc动态地为数据分配空间,并更新dim1、dim2和dim3,以反映我希望此结
struct
,在某种程度上模拟了知道自身大小的3D阵列的行为:
struct protoarray {
size_t dim1;
size_t dim2;
size_t dim3;
float* data;
};
我创建了两个类型为protoarray
的变量,在主机和设备端通过malloc和cudamaloc动态地为数据分配空间,并更新dim1
、dim2
和dim3
,以反映我希望此结构表示的数组大小。我读到,struct
应该通过copy传递。这就是我在内核中所做的
__global__ void kernel(curandState_t *state, protoarray arr_device){
const size_t dim1 = arr_device.dim1;
const size_t dim2 = arr_device.dim2;
for(size_t j(0); j < dim2; j++){
for(size_t i(0); i < dim1; i++){
// Do something
}
}
}
\uuuuu全局\uuuuuu无效内核(curandState\u t*state,protoarray arr\u设备){
const size_t dim1=arr_device.dim1;
const size_t dim2=arr_device.dim2;
对于(尺寸j(0);j
该结构通过copy传递,因此它的所有内容都复制到每个块的共享内存中。这就是我奇怪行为的地方,我希望你能帮我。假设我在主机端设置了arr\u device.dim1=2
。在内核内部调试并在循环的之一处设置断点时,检查arr_device.dim1
的值会产生类似16776576
的结果,其大小不足以导致溢出,但该值会像2
一样正确复制到dim1
,这意味着for
循环按照我的预期执行。作为一个附带问题,使用size\u t
这一基本unsigned long long int
的做法是否不好,因为GPU是由32位内核组成的
一般来说,将struct
和class
作为参数传递到内核中有多安全,是应该不惜一切代价避免的坏做法?我认为,如果类包含指向动态分配内存的成员,那么将指向类的指针传递给内核是很困难的,如果我想通过值传递它们,那么它们应该是非常轻量级的。这是一个部分答案,因为没有,很难/不可能猜测为什么在arr\u设备.dim1
中会看到无效值
该结构通过copy传递,因此它的所有内容都复制到每个块的共享内存中
不正确。内核参数存储在恒定内存中,该内存是设备全局的,而不是块特定的。它们不是存储在共享内存中(特定于块)
当线程运行时,它通常将参数从常量内存读入寄存器(同样,不是共享内存)
通常,将结构和类作为参数传递到内核中有多安全
我个人的经验法则是:如果结构/类
- 是微不足道的可复制;及
- 它的结构/类的所有成员都是为主机和设备端定义的,或者至少在设计时考虑了GPU的使用李>
然后,传递给内核应该是安全的
将结构和类作为参数传递到内核[-]是否应该不惜一切代价避免这种做法
否。但是请记住,大多数C++库只提供主机侧代码;并不是为了在GPU上使用而编写的。因此,我对在没有仔细检查的情况下使用非平凡类持谨慎态度
我认为,如果类包含指向动态分配内存的成员,那么将类指针传递给内核是很困难的
是的,这可能有问题。但是-如果您使用了cuda::memory::managed::allocate()
,cuda::memory::managed::make_unique()
或cudamalocmanaged()
,则这应该“正常工作”,即在访问时,相关内存页将根据需要被提取到GPU或CPU。见:
如果我想按值传递[对象到内核],它们应该是非常轻量级的
是,因为每个线程都必须从常量内存中读取每个参数,然后才能使用该参数。虽然恒定的内存允许这种情况相对较快地发生,但仍然需要将大量开销降至最低
还要记住,不能通过(C++)引用将任何内容传递给内核;这都是“按值”-对象本身或指向它的指针。这是一个部分答案,因为如果没有,很难/不可能猜测为什么您会在arr\u设备中看到无效值。dim1
该结构通过copy传递,因此它的所有内容都复制到每个块的共享内存中
不正确。内核参数存储在恒定内存中,该内存是设备全局的,而不是块特定的。它们不是存储在共享内存中(特定于块)
当线程运行时,它通常将参数从常量内存读入寄存器(同样,不是共享内存)
通常,将结构和类作为参数传递到内核中有多安全
我个人的经验法则是:如果结构/类
- 是微不足道的可复制;及
- 它的结构/类的所有成员都是为主机和设备端定义的,或者至少在设计时考虑了GPU的使用李>
然后,传递给内核应该是安全的
将结构和类作为参数传递到内核[-]是否应该不惜一切代价避免这种做法
否。但是请记住,大多数C++库只提供主机侧代码;并不是为了在GPU上使用而编写的。因此,我对在没有仔细检查的情况下使用非平凡类持谨慎态度
我认为,如果类包含指向动态分配内存的成员,那么将类指针传递给内核是很困难的
是的,这个