我想把指针传送到CUDA内存区域中,但是遇到了一定的问题,最终找到了解决方法,这里进行一下记录:
一、普通传递没有任何问题:
cudaMalloc((void**)&a_dev, 50 * sizeof(int));
a_host = (int*)malloc(sizeof(int) * 50);
for (int i = 0;i < 50;i++) a_host[i] = i;
cudaMemcpy(a_dev, a_host, 50 * sizeof(int), cudaMemcpyHostToDevice);
Cal <<<1, 50 >>> (a_dev);
cudaMemcpy(a_host, a_dev, 50 * sizeof(int), cudaMemcpyDeviceToHost); 在Cal程序里我把整个数组都设置为27,输出正常。
二、类内数组传递出现问题
class myRandom {
public:
myRandom() {}
int *a_dev;
int *a_host;
};
myRandom mr; 在Cal计算中,我传入的参数是__global__ void Calls(myRandom *pist)
然后在 Cal 里面通过pist->a_dev来指向需要修改的内存,但是修改结果并不对,原因是,就算是指针,传入到GPU中,也会重新拷贝一份。但是在GPU中复制了一份后,指针并没有去指向同一个区域?
按理来说我认为拷贝应该是指向同一个区域的,我又做了一个测试: 首先先证明地址不一样(传入GPU中确实进行了拷贝)
int* b_dev;
int b_host = 12;
cudaMalloc((void**)&(b_dev), sizeof(int));
printf("&&&&&&&&&&&&&&&&& %d", &mr);
Calls << <1, 50 >> > (&mr,b_dev);//
cudaMemcpy(&b_host, b_dev, sizeof(int), cudaMemcpyDeviceToHost);
printf("*************** %d\n", b_host); Cal函数:
global void Calls(myRandom *pist,int *b) {
int ii = threadIdx.x;
if (ii >= 50)return;
if (ii == 1)
*b = (int)(&pist);
} 打印结果不一样,说明传入时确实经过了拷贝。
再测试拷贝进去的结果。
printf("&&&&&&&&&&&&&&&&& %d", (mr.a_dev));
Cal里:
*b = (int)(pist->a_dev);
但是打印出来错误的结果。难道说这个内存区域是不存在的,是错误的?
类传入GPU的拷贝 我在myRandom里设了一个成员,
myRandom() { sss = 88;}
int sss; 然后再Cal里:
if (ii == 1)
*b = pist->sss; 结果没有被正确幅值。换句话说,传入的这个myRandom指针,在形参里其实里面什么都没有,只是一个地址罢了。
我以前传递的结构体是直接传递实体,而不是指针,所以:
解决方法:可以在GPU创建一块区域,把结构体拷贝进去.