我必须使用 CUDA 解决gpu上的代码问题,但我总是收到无法静态确定“函数名称”的堆栈大小的警告。
这是针对我正在从事的学生项目,该项目使用 CUDA 9.0 库以 C 编写,并且在 NVIDIA Quadro上运行K5000 gpu 。
每个单个线程必须执行一个函数,并且在此函数中,有两个递归调用相同的函数,之所以我要使用这两个递归调用,是因为它使代码对我来说简洁明了,但是如果有的话仅一个递归调用就不再存在堆栈大小问题。
这是我每次编译代码时遇到的错误:
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);
}
}
我只是想知道是否有可能解决递归调用的问题。
答案 0 :(得分:3)
CUDA支持递归。在CUDA中使用递归时,会出现此警告,并且没有NVIDIA记录的方法可以使警告消失(除非不使用递归)。
如果递归使用函数,则在大多数语言中,随着递归深度的增加,它将使用更多的堆栈空间。在CUDA中也是如此。您需要考虑到这一点,并为预期的最大递归深度提供足够的堆栈空间。限制递归深度以防止堆栈问题是常见的做法。
编译器无法在编译时发现最大的运行时递归深度,并且警告会提醒您这一点。
无论增加多少堆栈大小,警告都不会消失。出现警告是为了通知您,确保递归设计以及分配的堆栈空间能够正常工作是您的责任。编译器不会以任何方式验证堆栈大小的增加量是否足够。
答案 1 :(得分:1)
在CUDA中使用递归必须非常小心。递归使用堆栈内存,其限制为512 KB。默认值通常为1KB,这很容易溢出并使程序崩溃。您可以使用cudaThreadGetLimit()获取每个线程的堆栈大小。
建议: