cuda编程问题

use*_*164 0 cuda

我对cuda很新.我在设备仿真模式下在我的ubuntu 10.04上使用cuda.我编写了一个代码来计算以下数组的平方:

#include <stdio.h>
#include <cuda.h>
__global__ void square_array(float *a, int N)
    {
      int idx = blockIdx.x + threadIdx.x;
      if (idx<=N) 
       a[idx] = a[idx] * a[idx];
    }
int main(void)
    {
      float *a_h, *a_d; 
      const int N = 10;  
      size_t size = N * sizeof(float);
      a_h = (float *)malloc(size);        
      cudaMalloc((void **) &a_d, size);   
          for (int i=0; i<N; i++) a_h[i] = (float)i;
      cudaMemcpy(a_d, a_h, size, cudaMemcpyHostToDevice);
           square_array <<< 1,10>>> (a_d, N);

 cudaMemcpy(a_h, a_d, sizeof(float)*N, cudaMemcpyDeviceToHost);
      // Print results
      for (int i=0; i<N; i++) printf(" %f\n",  a_h[i]);

      free(a_h); 
cudaFree(a_d);
  return 0;
    } 
Run Code Online (Sandbox Code Playgroud)

当我运行此代码时它显示没有问题它给我正确的输出.

现在我的问题是,当我使用<<< 2,5 >>>或<<< 5,2 >>>时,结果是一样的.在gpu上发生了什么?我所理解的是,我只需要启动包含2个线程的5个块的cuda内核.任何人都可以解释我如何处理这个或实现启动(内核调用)?

现在我真正的问题是,当我用<<< 1,10 >>调用内核时,它没问题.它显示了完美的结果.但是当我用<<< 1,5 >>调用内核时,结果如下:

 0.000000
 1.000000
 4.000000
 9.000000
 16.000000
 5.000000
 6.000000
 7.000000
 8.000000
 9.000000
Run Code Online (Sandbox Code Playgroud)

类似地,当我减少或增加内核调用中的第二个参数时,它显示不同的结果,例如当我将其更改为<< 1,4 >>时,它显示以下结果:

 0.000000
 1.000000
 4.000000
 9.000000
 4.000000
 5.000000
 6.000000
 7.000000
 8.000000
 9.000000
Run Code Online (Sandbox Code Playgroud)

为什么这个结果会来?任何机构都可以解释内核启动调用的工作吗?

什么是blockdim类型变量包含?请帮助我理解内核调用启动和工作的概念?我搜索了编程指南,但他们没有很好地解释它.

tal*_*ies 5

idx内核代码中的计算不正确.如果您将其更改为:

int idx = blockDim.x * blockIdx.x + threadIdx.x;
Run Code Online (Sandbox Code Playgroud)

您可能会发现结果更容易理解.

编辑:对于任何给定的内核启动

square_array<<<gridDim,blockDim>>>(...)
Run Code Online (Sandbox Code Playgroud)

在GPU中,自动变量blockDim将包含在主机端内核启动中传递的blockDim参数的x,y和z组件.类似地,gridDim将包含在启动时传递的gridDim参数的x和y分量.