了解 cudaMalloc 分配矩阵的用法

understanding the usage of cudaMalloc to allocate a matrix

本文关键字:用法 cudaMalloc 分配 了解      更新时间:2023-10-16

在试图了解cudaMalloc()如何用于2d矩阵时,我遇到了以下帖子:

使用 cudaMalloc 分配矩阵

我想澄清 talonmies 给出的答案的一些要点,因此创建了这个单独的帖子。 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> 上述关于主机内存如何复制到设备内存的理解是否正确?

为了像 2-D 数组一样访问设备中的 (N,N) 内存块(由上面的第 5 行创建),我们现在需要将所有 pah[i] 的内容复制到设备中的指针。因此,前 N 个浮点指针是通过第 3 行中的代码在设备中创建的。然后使用第 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> 上述对主机内存如何复制到设备内存的理解是否正确?

也许。 我会说:"从主机到设备A[i]中包含的(主机)地址开始复制 N*sizeof(float) 字节,从pah[i]中包含的设备地址开始。

问题3>上述理解是否正确?

是的,我可能会用不同的方式表达一些事情,但我可能做出的改变似乎很小。 我想你已经明白了。

下面的代码行会完成这项工作,还是我犯了任何错误?

它应该是:

for (i=0; i<N; i++)
cudaMemcpy(A[i], pah[i], N*sizeof(float), cudaMemcpyDeviceToHost); 

您实际上是想撤消第 6 行中包含的操作。 每当您在使用 CUDA 代码时遇到问题时,不要忘记使用适当的 cuda 错误检查。