在尝试了解cudaMalloc()对于二维矩阵的工作原理时,我遇到了以下帖子:
Using cudaMalloc to allocate a matrix
我想澄清一些由on爪给出的答案,因此创建了这个单独的帖子。 Talonmies提供了以下解决方案。
float **pa;
float **pah = (float **)malloc(pah, N * sizeof(float *));
cudaMalloc((void***)&pa, N*sizeof(float*));
for(i=0; i<N; i++) {
cudaMalloc((void**) &(pah[i]), N*sizeof(float));
cudaMemcpy (pah[i], A[i], N*sizeof(float), cudaMemcpyHostToDevice);
}
cudaMemcpy (pa, pah, N*sizeof(float *), cudaMemcpyHostToDevice);
第5行中的代码:
cudaMalloc((void**) &(pah[i]), N*sizeof(float));
在设备存储器中创建一个块N * float空间,并将设备存储器的第i个块的起始地址放入pah [i]。 pah [i]驻留在主机内存中,但是每个pah [i]的内容都是在设备中创建的内存的地址。
问题1>以上理解正确吗?
第6行中的代码:
cudaMemcpy (pah[i], A[i], N*sizeof(float), cudaMemcpyHostToDevice);
将A [i]从主机复制到pah [i]的内容(pah [i]的内容是N * float块中每个块的起始地址)。
问题2>对主机内存如何复制到设备内存的上述理解正确吗?
为了像二维数组一样访问设备中的(N,N)个内存块(由上面的第5行创建),我们现在需要将所有pah [i]的内容复制到指针中。设备。因此,首先通过第3行中的代码在设备中创建N个浮点指针,然后使用第8行中的代码将N * float块的地址从pah [i]复制到pa。之后,我们将能够访问位于主机中的A [i] [j]和位于设备中的pa [i] [j]的内容。
问题3>以上理解正确吗?
现在说我生成N * N线程,并使用每个线程的线程ID更改pa [i] [j]的内容。然后,我想将驻留在设备中的pa [i] [j]的内容复制回驻留在主机中的A [i] [j]。下面的代码行会完成这项工作吗,还是我犯了任何错误?
for (i=0; i<N; i++)
cudaMemcpy(A[i], pa[i], N*sizeof(float), cudaMemcpyDeviceToHost);
在此先感谢所有帮助我阐明这些疑问/问题的人。
最好
最佳答案
问题1>以上理解正确吗?
是。
问题2>对主机内存如何复制到设备内存的上述理解正确吗?
也许。我会说:“将N * sizeof(float)字节从A[i]
中包含的(主机)地址开始,从主机复制到设备,并从pah[i]
中包含的设备地址开始。”
问题3>以上理解正确吗?
是的,我可能在措辞上有些不同,但所做的更改似乎很小。我想你已经明白了。
下面的代码行能完成这项工作吗,还是我犯错了?
它应该是:
for (i=0; i<N; i++)
cudaMemcpy(A[i], pah[i], N*sizeof(float), cudaMemcpyDeviceToHost);
您实际上是想撤消第6行中包含的操作。
当您遇到CUDA代码问题时,请不要忘记使用proper cuda error checking。