在CUDA中使用递归时,为什么会收到警告?

时间:2019-01-18 13:43:39

标签: recursion cuda

我必须使用 CUDA 解决gpu上的代码问题,但我总是收到无法静态确定“函数名称”的堆栈大小的警告

这是针对我正在从事的学生项目,该项目使用 CUDA 9.0 库以 C 编写,并且在 NVIDIA Quadro上运行K5000 gpu
每个单个线程必须执行一个函数,并且在此函数中,有两个递归调用相同的函数,之所以我要使用这两个递归调用,是因为它使代码对我来说简洁明了,但是如果有的话仅一个递归调用就不再存在堆栈大小问题。

这是我每次编译代码时遇到的错误:

enter image description here

CUDA 支持递归函数调用,但我不明白为什么在有两个递归调用时会造成问题。

__device__ void bitonicMergeGPU(float *arr, int l, int indexT, int order) 
{
    int k,p;

    if(l > 1)
    {
        p = l/2;

        for(k=indexT;k<indexT+p;k++)
        {
            //Compare the values.
            compareAndExchange(arr,k,k+p,order);
        }

        //THIS IS WHERE I GET THE ERROR

        bitonicMergeGPU(arr,p,indexT,order);
        bitonicMergeGPU(arr,p,indexT+p,order);
    }
}

我只是想知道是否有可能解决递归调用的问题。

2 个答案:

答案 0 :(得分:3)

CUDA支持递归。在CUDA中使用递归时,会出现此警告,并且没有NVIDIA记录的方法可以使警告消失(除非不使用递归)。

如果递归使用函数,则在大多数语言中,随着递归深度的增加,它将使用更多的堆栈空间。在CUDA中也是如此。您需要考虑到这一点,并为预期的最大递归深度提供足够的堆栈空间。限制递归深度以防止堆栈问题是常见的做法。

编译器无法在编译时发现最大的运行时递归深度,并且警告会提醒您这一点。

无论增加多少堆栈大小,警告都不会消失。出现警告是为了通知您,确保递归设计以及分配的堆栈空间能够正常工作是您的责任。编译器不会以任何方式验证堆栈大小的增加量是否足够。

答案 1 :(得分:1)

在CUDA中使用递归必须非常小心。递归使用堆栈内存,其限制为512 KB。默认值通常为1KB,这很容易溢出并使程序崩溃。您可以使用cudaThreadGetLimit()获取每个线程的堆栈大小。

建议:

  1. 使用非递归方法重新设计算法/功能。效率通常非常相似。
  2. 使用cudaThreadSetLimit()增加每个线程的堆栈大小,但不超过限制,例如512KB。