2014-01-24 35 views
2

Opencl不支持遞歸函數,但它是否也包含間接版本呢?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發佈之前,我是否必須使用自定義「堆棧」實現來進行間接遞歸?

回答

7

OpenCL不支持遞歸控制流,其中包括相互遞歸。因此,爲了確保您的代碼能夠在您希望定位的每個平臺上正常工作,您應該避免使用任何形式的遞歸,而應使用迭代方法編寫算法。

實際上,OpenCL編譯器可能能夠處理某些遞歸算法。例如,如果您的函數是tail-recurisve,那麼編譯器可以通過應用標準的尾部調用優化技術來產生非recurisve形式。我剛剛嘗試了您發佈的第二個遞歸代碼片段,並且它被多個OpenCL編譯器接受。第一個代碼片段導致它們全部崩潰,這表明它們不能應用必要的轉換來避免遞歸調用(儘管顯然它們應該產生適當的錯誤消息而不是崩潰)。因此,您可能能夠通過一些OpenCL實現簡單遞歸,但爲了在不同平臺間實現最大的可移植性,我強烈建議您避免這種情況。