CUDA结构体或类的传递内存实验

346 阅读2分钟

我想把指针传送到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创建一块区域,把结构体拷贝进去.