将int与threadIdx.x进行比较时,CUDA内核无限循环

时间:2013-12-20 17:05:54

标签: cuda

我遇到了一个更大的内核问题,但它似乎要反映到以下代码,内核永远不会返回。有人可以解释一下为什么会出现无限循环吗?

__global__ void infinite_while_kernel(void)
{
    int index = 0;
    while (index >= threadIdx.x) {
        index--;
    }
    return;
}

int main(void) {
    infinite_while_kernel<<<1, 1>>>();
    cudaDeviceSynchronize();
    return 0;
}

另外,下面的内核也会卡住:

__global__ void not_infinite_while_kernel(void)
{
    int index = 0;
    while (index >= (unsigned int) 0u*threadIdx.x) {
        index--;
    }
return;
}

在原始内核中用threadIdx.x替换0将返回,如预期的那样。我正在使用v5.5工具包,并使用-arch=sm_20 -O0标志进行编译。在特斯拉M2090上运行。我目前无法访问任何其他硬件,也无法访问工具包版本(这不是我的系统)。

1 个答案:

答案 0 :(得分:3)

这段代码也挂在普通的C ++中(试一试):

int main(){

  int index = 0;
  while (index >= 0U){
    index--;
    }
  return 0;
}

将有符号值与无符号值进行比较时,compiler converts the signed value to unsigned

threadIdx.x是无符号值。代码中没有标记的0常量不是。

作为无符号比较,您的测试始终为true,因此while循环永远不会退出。

另请注意,您的__global__功能应使用void进行修饰。

最后,在内核启动后代码中没有cudaDeviceSynchronize()或其他障碍,无论如何,即使内核挂起,程序也会“正常”退出。

所以我认为您发布的代码实际上并不会重现您所描述的问题,但如果您添加cudaDeviceSynchronize()它将会发生。