【问题标题】:Issue With mapping 2D to 1D array in CUDA在 CUDA 中将 2D 映射到 1D 数组的问题
【发布时间】:2013-05-03 00:54:05
【问题描述】:

我在 CUDA 中编写了以下代码

__global__ void test(int *b_dev)
{
  int index=blockDim.x*blockIdx.x+threadIdx.x;
  b_dev[index]=1;
 }

 int main()
 {
   int **a;
   int *b_dev;
   a=(int**)malloc(sizeof(int*)*4);
   for(i=0;i<4;i++)
     a[i]=(int*)malloc(sizeof(int)*4);

   //initialise array a here with 0

   cudaMalloc((void**)&b_dev,sizeof(int)*16);
   cudaMemcpy(b_dev,a,sizeof(int)*16,cudaMemcpyHostToDevice);
   test<<<4,4>>>(dev_b);
   cudaMemcpy(a,b_dev,sizeof(int)*16,cudaMemcpyDeviceToHost);
   for(i=0;i<4;i++)
     for(j=0;j<4;j++)
        cout<<a[i][j];
  }

我在主机中有这个二维数组,我将它展平为一维数组并在 gpu 中处理,但是当我尝试在主机中打印数组 a 时,这段代码会产生分段错误,但是当我注释掉 b_dev[valindex]=1 行时在内核中,它使用初始化的零打印数组a。可视化 c++ 调试器表明

CXX0030:无法评估错误表达式。

请带我继续

【问题讨论】:

  • 您将数据错误地复制到 gpu 或从 gpu 复制。以这种方式分配的 2D 数组不能通过使用单个内存副本直接复制。另外,指定的语句不应该是b_dev[index]=1; 吗?
  • 是的,它是 b_dev[index]=1。这是一个错字..你能告诉我如何实现这一点
  • 或者有其他方法吗?
  • 如果你有一个二维数组,你将需要多个 memcpy 调用。您是否需要使用二维数组,还是只能在任何地方使用一维数组?
  • 如果我将主机 2d 数组展平为主机 1d 数组,我是否能够运行它?如果这样就足够了

标签: cuda


【解决方案1】:

当您以您的方式分配数组时,您无法保证每个数组在内存中都是连续的。更具体地说,在您的示例中,您有一个 int** 数组 a,它由 4 个 int* 数组、a[0]a[1]a[2]a[3] 组成。在每个数组 a[i] (其中 i 是二维数组的数组索引)内,内存将是连续的。但是,不能保证数组a[i] 的内存和数组a[i+1] 的内存是。也就是说,在您对malloc 的调用之间,分配的内存可以来自您的免费存储中的任何位置,并且它们是否连续取决于malloc。 (顺便说一句,如果您在堆栈上分配内存,那么它将是连续的,或者在堆上作为一维数组)。

因此,您不能指望 1 次调用 cudaMemcpy 来复制您的所有数组。相反,您必须为每个一维数组执行多次 cudaMemcpy 调用才能复制所有数组,并对目标指针进行指针算术运算以确保将它们复制到正确的位置。

处理连续二维数据时,可以使用cudaMemcpy2D,其签名为:

cudaError_t cudaMemcpy2D ( void* dst, size_t dpitch, const void* src, size_t spitch, size_t width, size_t height, cudaMemcpyKind kind )

如果您知道源音高和目标音高,则可以使用它,并在使用数据时考虑音高。但是,此函数假定数据维度是连续的,因此在您的情况下它对您没有帮助。

当然,最简单的解决方案是选择一个数组维度协议并坚持使用它(例如,要么将所有内存都设为 2D 或全部 1D,但除非你有令人信服的理由,否则不要混合它们)。

如果我不留下relevant CUDA documentation about cudaMemcpy的链接,我也会失职

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-12
    • 2020-03-19
    • 2012-03-28
    • 1970-01-01
    • 1970-01-01
    • 2021-05-31
    相关资源
    最近更新 更多