Opencl不支持递归函数,但这也包括间接版本吗?
void recursiveA(int *a,int b) // call this first to start recursion
{
a[b]=3;
if(b<10)
{
recursiveB(a,b+1); // A calls B
}
}
void recursiveB(int *a, int b)
{
a[b]=3;
if(b<10)
{
recursiveA(a,b+1); // B calls A while A still not finished before
// and entry point & arguments of A are corrupt ?
}
}
而不是
void recurse(int *a, int b)
{
a[b]=3;
if(b<10)
{
recurse(a,b+1); // some OpenCL devices does not have the ability so this is not
// possible in OpenCL
}
}
那么,即使第一个“R”没有完成,我们可以从另一个函数调用“R”函数吗?每次调用它们时,这些函数只对参数使用相同的常量地址? 在Opencl 2.0发布之前,我是否必须使用自定义“堆栈”实现来进行间接递归?
答案 0 :(得分:7)
OpenCL不支持递归控制流,包括相互递归。因此,为了确保您的代码在您可能希望定位的每个平台上正常工作,您应该避免使用任何形式的递归,而是使用迭代方法编写算法。
实际上,OpenCL编译器可能能够很好地处理某些递归算法。例如,如果您的函数是tail-recurisve,那么编译器可以通过应用标准尾调用优化技术来生成非重新形式。我刚刚尝试了你发布的第二个递归代码片段,它被多个OpenCL编译器接受了。第一个代码片段导致它们全部崩溃,这表明它们无法应用必要的转换来避免递归调用(尽管显然它们应该产生合适的错误消息而不是崩溃)。
因此,您可以通过一些OpenCL实现轻松进行简单递归,但为了在不同平台上实现最大可移植性,我强烈建议您避免使用它。