CUDA 内核的参数

Posted

技术标签:

【中文标题】CUDA 内核的参数【英文标题】:Parameters to CUDA kernels 【发布时间】:2011-11-28 21:22:42 【问题描述】:

在为特定线程配置调用 CUDA 内核时,是否有任何严格的规则 内核参数应该驻留在哪个内存空间(设备/主机)中,它们应该是什么类型?

假设我使用

启动一维线程网格
kernel<<<numblocks, threadsperblock >>> (/*parameters*/)

我可以传递一个整数参数int foo,它是一个主机-整数变量, 直接到CUDA内核?或者我应该将cudaMalloc 用于单个整数的内存说dev_foo,然后将cudaMemcpy foo 转换为devfoo,然后将devfoo 作为内核参数传递?

【问题讨论】:

【参考方案1】:

内核参数的规则是 C++ 参数传递规则的逻辑结果以及设备和主机内存在物理上是分开的事实。

CUDA 不允许通过引用传递参数,您必须小心使用指针。

具体来说,您必须按值传递参数。传递用户定义的类型要求默认的复制构造函数或您自己的复制构造函数(如果存在)不包含任何内存分配(带有“new”或“malloc”的堆分配)。

总之,按值传递适用于整数、浮点或其他基本类型,以及简单的平面用户定义结构或类对象。

【讨论】:

自编写此答案以来,CUDA 已经取得了长足的进步。即使写了答案,我相信如果基础数据被固定和映射,使用传递引用应该是合法的/可能的。今天,通过UM/managed memory 以及固定/映射内存(例如cudaHostAlloc())使用传递引用是合法的/可能的【参考方案2】:

您只需将cudaMalloc()cudaMemcpy() 用于数据块。不是单身ints 之类的。您也可以将structs 作为参数传递,只要它们没有指向主机内存中数据块的成员。

因此,根据经验:如果您将指针传递给内核,请确保它指向设备内存。

【讨论】:

以上是关于CUDA 内核的参数的主要内容,如果未能解决你的问题,请参考以下文章

CUDA内核启动参数解释正确吗?

将结构作为参数传递给 CUDA 内核的行为

将包含向量的结构传递给CUDA内核

具有 CUDA 内核的动态数据的 C 结构?

访问不同 CUDA 内核中的类成员

简单cuda内核添加:2432内核调用后内存非法