CUDA超时? / fermi / gtx465

时间:2010-07-12 05:57:46

标签: timeout cuda nvidia

我在MS VS2005上使用CUDA SDK 3.1,GPU GTX465 1 GB。我有这样的内核函数:

__global__ void CRT_GPU_2(float *A, float *X, float *Y, float *Z, float *pIntensity, float *firstTime, float *pointsNumber)
{


  int holo_x = blockIdx.x*20 + threadIdx.x;
  int holo_y = blockIdx.y*20 + threadIdx.y;

  float k=2.0f*3.14f/0.000000054f;

  if (firstTime[0]==1.0f)
  {
   pIntensity[holo_x+holo_y*MAX_FINAL_X]=0.0f; 
  }

  for (int i=0; i<pointsNumber[0]; i++)
  {
   pIntensity[holo_x+holo_y*MAX_FINAL_X]=pIntensity[holo_x+holo_y*MAX_FINAL_X]+A[i]*cosf(k*sqrtf(pow(holo_x-X[i],2.0f)+pow(holo_y-Y[i],2.0f)+pow(Z[i],2.0f)));
  }

  __syncthreads(); 


}

这是调用内核函数的函数:

extern "C" void go2(float *pDATA, float *X, float *Y, float *Z, float *pIntensity, float *firstTime, float *pointsNumber)
{
 dim3 blockGridRows(MAX_FINAL_X/20,MAX_FINAL_Y/20);
 dim3 threadBlockRows(20, 20);

 CRT_GPU_2<<<blockGridRows, threadBlockRows>>>(pDATA, X, Y, Z, pIntensity,firstTime, pointsNumber); 
 CUT_CHECK_ERROR("multiplyNumbersGPU() execution failed\n");
 CUDA_SAFE_CALL( cudaThreadSynchronize() );
}

我正在将所有参数加载到此函数中(例如,在一次循环迭代中为每个参数添加4096个元素)。总的来说,我希望在所有循环迭代之后为每个参数制作32768个元素的内核。

MAX_FINAL_X为1920,MAX_FINAL_Y为1080。

当我开始alghoritm时,第一次迭代进行得非常快,在一次或两次迭代后,我得到有关CUDA超时错误的信息。我在GPU gtx260上使用了这个alghoritm,据我记得它做得更好......

你可以帮助我......也许我在这个算法中根据新的Fermi arch做了一些错误?

3 个答案:

答案 0 :(得分:1)

您的GPU是否已连接到显示器?如果是这样,我相信默认情况下,内核执行将在5秒后中止。您可以使用cudaGetDeviceProperties检查内核执行是否会超时 - 请参阅reference page

答案 1 :(得分:1)

  1. 最好打电话 CUT_CHECK_ERROR之后 cudaThreadSynchronize()。因为 内核运行异步,你必须 等待内核结束才知道 错误...也许在第二次迭代中,您收到错误 从第一个内核使用。
  2. 确定 在最有趣的变量中有一些有效数字 pointsNumber[0](可能会导致 长内循环)。
  3. 你也可以 提高内核的速度 功能:
    • 使用更好的块​​。线程配置20x20将导致内存使用速度非常慢(请参阅编程指南和最佳实践)。尝试使用块16x16。
    • 不要使用pow(..., 2.0)功能。使用SQR宏(#define SQR(x) (x)*(x)
    • 会更快
    • 您不使用共享内存,因此不需要__syncthreads()
  4. PS:您还可以将值参数传递给CUDA函数,而不仅仅是指针。速度是一样的。

    PPS:请提高代码的可读性......现在你必须编辑六个地方来改变块配置......在内核中你可以使用blockDim变量,你可以在go2函数中使用常量。 您也可以使用bool firstTime - 它会比float更好。

答案 2 :(得分:1)

在内核的循环中,你在相同的数组中写入,从中读取 - 对于全局内存使用情况,它是最差的,因为来自不同块的warp会相互等待。