0

当我尝试从设备执行的函数中访问全局数组时,我发现了一些困难:

float globTemp[3][3] = "some value in here";
__device__ float* globTemp_d;

__global__ void compute(int *a, int w)
{
  int x = threadIdx.x + blockDim.x * blockIdx.x;
  int y = threadIdx.y + blockDim.y * blockIdx.y;
  int i = y*w+x;
  if(x<3 && y<3)
    a[i] = 1+globTemp_d[i];
}

int hostFunc(){
   float *a_d;
   cudaMalloc((void**)&a_d, 3*3*sizeof(int));
   cudaMalloc((void**)&globTemp_d, 3*3*sizeof(int));
   cudaMemcpy(globTemp_d,globTemp, 3*3*sizeof(float), cudaMemcpyHostToDevice);
   compute<<<1,1>>>(a_d,3);
   cudaMemcpy(a,a_d, 3*3*sizeof(float), cudaMemcpyDeviceToHost);
}

但是,当我尝试访问 globTemp_d[i] 时出现 seg 错误。我在这里做错了吗?

4

1 回答 1

1

您的代码存在各种问题:

  1. 您的网格是 1D 线程块的 1D 网格(实际上您正在启动 1 个线程的单个块),但您的内核被编写为好像它期望 2D 线程块结构(使用.x.y内置变量)。单个线程肯定无法完成工作,并且一维线程块无法与您的内核代码一起使用。
  2. __device__变量不能cudaMallocand访问cudaMemcpy。我们使用一组不同的 API 调用,例如cudaMemcpyToSymbol.
  3. 你没有做任何cuda 错误检查,当你遇到困难时总是建议这样做。您应该对 API 调用内核调用进行 cuda 错误检查。
  4. 您将float变量 ( a_d) 与int内核参数 ( int *a) 中的变量混合在一起,所以我认为这段代码不会在没有警告的情况下编译。如果您忽略它,那当然会导致奇怪的行为。

这是我在修复所有错误时最接近您的代码的方法:

#include <stdio.h>

__device__ float* globTemp_d;

__global__ void compute(float *a, int w)
{
  int x = threadIdx.x + blockDim.x * blockIdx.x;
  int y = threadIdx.y + blockDim.y * blockIdx.y;
  int i = (y*w)+x;
  if((x<3) && (y<3))
    a[i] = 1.0f+globTemp_d[i];
}

int main(){
   float *a_d, *d_globTemp;
   float globTemp[3][3] = {0.1f, 0.2f, 0.3f, 0.4f, 0.5f, 0.6f, 0.7f, 0.8f, 0.9f};
   float a[(3*3)];
   dim3 threads(3,3);
   dim3 blocks(1);
   cudaMalloc((void**)&a_d, 3*3*sizeof(float));
   cudaMalloc((void**)&d_globTemp, 3*3*sizeof(float));
   cudaMemcpy(d_globTemp,globTemp, 3*3*sizeof(float), cudaMemcpyHostToDevice);
   cudaMemcpyToSymbol(globTemp_d, &d_globTemp, sizeof(float *));
   compute<<<blocks,threads>>>(a_d,3);
   cudaMemcpy(a,a_d, 3*3*sizeof(float), cudaMemcpyDeviceToHost);

   printf("results:\n");
   for (int i = 0; i<(3*3); i++)
     printf("a[%d] = %f\n", i, a[i]);
   return 0;
}

可以通过省略__device__变量并仅将d_globTemp其作为参数传递给内核并使用它代替对globTemp_d. 但是我没有做那种简化。

于 2013-06-05T01:37:32.803 回答