cudaMemcpy()在使用Type **时给出了段错误

时间:2014-11-16 13:26:44

标签: memory-management cuda segmentation-fault cuda-gdb

我想将双指针对象复制到主机并在GPU设备上对其进行计算。在对设备执行cudaMemcpy时,它会抛出SEGFAULT。

BMP Input;
Input.ReadFromFile( fileName );
WIDTH = Input.TellWidth();
HEIGHT = Input.TellHeight();
RGBApixel** imageData = new RGBApixel* [HEIGHT];
for (int i = 0; i < HEIGHT; i++) 
    imageData[i] = new RGBApixel [WIDTH];

for(int j=0;j<Input.TellHeight();j++){
    for(int i=0;i<Input.TellWidth();i++){
      imageData[j][i] = Input.GetPixel(i,j);
    }
  }
long long imageSize = WIDTH*HEIGHT*sizeof(RGBApixel *);

RGBApixel** dev_imgdata,dev_imgdata_out;
//Allocating cudaMemory
cudaMalloc( (void **) &dev_imgdata, imageSize );
cudaMalloc( (void **) &dev_imgdata_out, imageSize );

现在下面的行抛出了段错误

cudaMemcpy(dev_imgdata,imageData,imageSize,cudaMemcpyHostToDevice);

2 个答案:

答案 0 :(得分:1)

声明RGBApixel** imageData = new RGBApixel* [HEIGHT];时,您绝对不能保证imageData会占用连续的内存块。

cudaMemcpy 将内存的连续块复制到设备RAM中。您的语句会尝试复制每个矩阵行的起始地址,但不会复制实际数据。此外,当使用cudaMalloc时,您需要为每一行正确分配,就像您对主机缓冲区所做的那样。

你需要做的是将imageData声明为RGMAPixel * - 基本上将矩阵放在一个向量中并使用正确的索引,它将起作用。

您也可以一次复制每一行,但这不是一个很好的做法,因为每次内存访问都需要额外的间接,而会破坏缓存效率

答案 1 :(得分:0)

此外,请确保在编译程序时使用-arch sm_20为图形卡启用额外选项(如果它具有Capability 2.0)。没有它,我相信你不能使用double,结果是不可预测的(或者双倍减少浮动)