在主机代码中使用 cudaMalloc() 返回的指针上执行算术运算



我正在阅读 Cuda 示例书,我遇到了这句话:

但是,程序员有责任不取消引用指针 由 cudaMalloc() 从主机上执行的代码返回。主机代码可能 传递此指针,对其执行算术运算,甚至将其转换为其他指针 类型。但是您不能使用它从内存中读取或写入。

具体来说,"在 cudaMalloc() 返回的指针上执行算术"是如何完成的?

我尝试在调用内核之前和之后运行带有 2 行附加的附加代码,但它对输出没有影响(有或没有这些行的输出为 12)。

#include <iostream>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
__global__
void add(int a, int b, int *c)
{
*c += a + b;
}
int main()
{
int *c, d;
cudaMalloc((void**)&c, sizeof(int));
*c = 10;
add << <1,1>> > (5,7,c);
*c += 5;
cudaMemcpy(&d, c, sizeof(int), cudaMemcpyDeviceToHost);
std::cout << d<<std::endl;
return 0;
}

我是初学者,感谢您的帮助。

指针算术是一个与 C 和 C++ 相关的概念,它不是 CUDA 独有的或特定的。

这不是指针算术的示例:

*c = 10;

这也不是:

*c += 5;

这些都是对指针所指向内容的修改,而不是指针本身。 指针算术涉及对指针值本身的调整。(顺便说一下,您显示的代码在 CUDA 中是非法的 - 在主机代码中取消引用普通设备指针是不合法的。*c取消引用指针c的操作。 它与指针算术不同。

假设我的设备内存分配为 1024int数量:

cudaMalloc(&data, 1024 * sizeof(int));

现在假设我想让 CUDA 内核的第一次调用开始在数组的开头工作,第二次调用 CUDA 内核开始在数组的中点工作,但否则执行相同的工作。

我可能会做这样的事情,第二个内核调用有一个涉及指针算术的参数:

kernel<<<...>>>(data, 512);
kernel<<<...>>>(data+512, 512);

data+512参数涉及指针算术。 这将传递一个指向内核的指针,该指针指向数据数组的中点,而不是数组的开头。 如果我想在主机代码中携带这个指针,我可以做:

int *datahalf = data+512;

最新更新