我正在通过实例书阅读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;
}
我是初学者,非常感谢你的帮助。
答案 0 :(得分:2)
pointer arithmetic是与C和C ++相关的概念,它不是唯一的或特定于CUDA。
这不是指针算术的一个例子:
*c = 10;
也不是这样:
*c += 5;
这些都是指针指向的修改,而不是指针本身。指针算法涉及对指针值本身的调整。 (顺便说一句,你所显示的代码在CUDA中是非法的 - 在主机代码中取消引用普通设备指针是不合法的。*c
是一个解除引用指针{{1}的操作。它与指针算法不同。)
假设我的设备内存分配为1024 c
个数量:
int
现在假设我想让CUDA内核的第一次调用开始在数组的开头工作,并且第二次调用CUDA内核以开始在数组的中点工作,但是否则执行相同的工作
我可能会这样做,第二次内核调用有一个涉及指针算术的参数:
cudaMalloc(&data, 1024 * sizeof(int));
kernel<<<...>>>(data, 512);
kernel<<<...>>>(data+512, 512);
参数涉及指针算术。这将传递指向内核的指针,该指针指向数据数组的中点,而不是数组的开头。如果我想在主机代码中携带这个指针,我可以这样做:
data+512