Cuda 将参数按值传递给核函数时,参数复制到哪里?

Cuda 将参数按值传递给核函数时,参数复制到哪里?,cuda,gpu-constant-memory,Cuda,Gpu Constant Memory,我是CUDA编程的初学者,有一个问题 当我按值传递参数时,如下所示: __global__ void add(int a, int b, int *c) { // some operations } 由于变量a和b被传递给内核函数add,作为函数调用堆栈中复制的值,我猜复制时需要一些内存空间 如果我是对的,复制这些参数的额外内存空间是吗 在GPU中还是在主机的主内存中 我想知道这个问题的原因是我应该向内核函数传递一个大结构 我还想传递结构的指针,但似乎需要这些方法来调用结构和每个成员变

我是CUDA编程的初学者,有一个问题

当我按值传递参数时,如下所示:

__global__ void add(int a, int b, int *c) {
    // some operations
}
由于变量ab被传递给内核函数add,作为函数调用堆栈中复制的值,我猜复制时需要一些内存空间

如果我是对的,复制这些参数的额外内存空间是吗 在GPU中还是在主机的主内存中

我想知道这个问题的原因是我应该向内核函数传递一个大结构


我还想传递结构的指针,但似乎需要这些方法来调用结构和每个成员变量的cudamaloc

非常简短的答案是,CUDA内核的所有参数都是按值传递的,主机通过API将这些参数复制到GPU上的专用内存参数缓冲区中。目前,该缓冲区存储在恒定内存中,每个内核启动的参数限制为4kb——请参阅


更详细地说,PTX标准(从compute capability 2.0硬件和CUDA ABI出现以来的技术上讲)定义了一个专用的逻辑状态空间调用
.param
,它保存内核和设备参数参数。看见引用该文件:

每个内核函数定义都包含一个可选的 参数。这些参数是可寻址的只读变量 在.param状态空间中声明。从主机传递到服务器的值 使用
ld.param
说明书内核参数变量在所有系统中共享 网格内的CTA

委员会还注意到:

注意:参数空间的位置是特定于实现的。例如,在某些实现中,内核参数驻留在 全局内存。参数和之间未提供访问保护 在这种情况下是全局空间。类似地,函数参数也被映射 根据参数传递寄存器和/或堆栈位置 应用程序二进制接口的函数调用约定 (ABI)

因此,参数状态空间的精确位置是特定于实现的。在CUDA硬件的第一次迭代中,它实际上映射到内核参数的共享内存和设备函数参数的寄存器。然而,由于Compute2.0硬件和PTX2.2标准,它在大多数情况下映射到内核的恒定内存。文件中说:

常量(
.const
)状态空间是初始化的只读内存 由主持人主持。使用
ld.const
指示恒定内存大小受限,当前有限 至64 KB,可用于保持静态大小的常量 变量。还有640 KB的固定内存, 组织为十个独立的64 KB区域。司机可以分配 初始化这些区域中的常量缓冲区,并将指针传递给 缓冲区作为内核函数参数。因为这十个地区 不连续,驱动程序必须确保恒定缓冲区是连续的 分配,使每个缓冲区完全适合64 KB的区域,并且 不跨越区域边界

静态大小的常量变量具有可选的变量初始值设定项;没有显式初始值设定项的常量变量是 默认情况下初始化为零。由 驱动程序由主机初始化,指向这些缓冲区的指针是 作为参数传递给内核

[我的重点]


因此,虽然内核参数存储在常量内存中,但这与映射到
.const
状态空间的常量内存不同,可以通过在CUDA C或Fortran或Python中将变量定义为
\uuuuuu constant\uuuuu>/code>来访问。相反,它是一个由驱动程序管理的内部设备内存池,程序员无法直接访问。

内核调用的传递值参数放在
\uuuuuuu常量
内存中,这是一种特殊的设备内存。在内核代码开始时(通常),所需的参数将从
\uuuuu constant\uuuu
内存复制到寄存器中。编程指南中介绍了这一点。