2011-10-17 66 views
3

我有遞歸但不是尾遞歸內聯函數,我希望gcc展開遞歸。是的,我當然使用g++ -O3 -funroll-loopsg ++/gcc在展開遞歸內聯函數時有多有效?

inline void recurse_fun(..., unsigned depth = 0, unsigned max_depth = 40) { 
    if (++depth > max_depth) return; 
    for (auto i = ..., iend = ...; i != iend; i++) { 
     if (...) continue; 
     ... 
     recurse_fun(...,depth,max_depth); 
    } 
} 

我可以很容易地通過手動操作一個stack<...>對象,GCC應該正常展開代替這一點,但它不會被視爲相當優雅或維護。

我應該真的嘗試分析這兩個版本無論如何,但我很好奇,如果任何人都可以有信心地說,一些最新的海灣合作委員會版本會或不會正確處理這個。

+1

相關:http://ridiculousfish.com/blog/posts/will-it-optimize.html –

+0

你能看看生成的彙編語言嗎?此外,1)任何這麼做的函數都會從內聯中看到微不足道的好處,並且2)編譯器是否內聯遞歸函數?這會讓我感到驚訝。 3)如果你的意思是展開內部循環,那麼如果內部有一個函數調用,那麼也不會節省很多。 –

+0

不錯的發現,喬希李! :)是的,我認爲閱讀彙編程序比閱讀探查程序Mike Dunlavey容易得多。 –

回答

1

GCC(至少最近的版本,如4.5或4.6)確實展開了一些尾遞歸調用。 當然你需要問它優化(所以需要-O2-O3)。

要了解它做什麼,你可以

  • 詢問的東西組裝輸出像gcc -O3 -fverbose-asm -S yoursource.c
  • 詢問各種dump files,像gcc -c -fdump-tree-all -fdump-ipa-all -O3 yoursource.c(還有其他轉儲文件)

請注意,GCC會打印大量(數百個)轉儲文件。轉儲文件僅用於幫助GCC開發人員或GCC插件開發人員(或GCC MELT開發人員)。不要指望它們保持從GCC的一個版本到下一個版本的相同格式。

轉儲文件的編號是無用的:它不是按時間順序或邏輯。

而且轉儲選項有可能在明年發佈的GCC(4.7在2012年,可能)改變