2008-11-22 24 views
0

我對它是什麼有一個想法。我的問題是: -尾調用優化(TCO)後的性能測試

1.)如果我編程我的代碼是適合尾巴呼叫優化(最後語句在函數[遞歸函數]只是一個函數調用,沒有其他操作那裏),那麼我需要設置任何優化級別,以便編譯器執行TCO。編譯器在什麼樣的優化模式下執行TCO,針對空間或時間進行優化。

2)我如何找出所有的編譯器(MSVC,GCC,ARM-RVCT)不支持TCO

3)假設一些編譯器TCO,我們啓用它那麼,有什麼辦法發現該編譯器實際上完成了TCO?將代碼大小,告訴它或週期採取執行它會告訴或兩者?

〜AD

回答

0

如果你希望你的編譯器做尾調用優化,只檢查或者

一)該優化級別將進行編譯或

B的DOC)檢查asm,如果函數會自動調用(你甚至不需要大的asm知識來再次發現函數的符號)

如果你真的很想要尾遞歸,我的問題是:

爲什麼不自己執行尾部呼叫刪除?它意味着除去遞歸,除非它是可移動的,那麼它不僅可以被編譯器在低級別上運行,而且在算法級別上也可以運行,那麼你可以直接將它編程到你的代碼中(這意味着除了去尋找循環而不是對自己的呼叫)。

2

大多數編譯器支持TCO,這是一種相對較舊的技術。至於如何使用特定的編譯器啓用它,請查看編譯器的文檔。海灣合作委員會將啓用除-O1之外的每個優化級別的優化,我認爲這是特定的選項是-foptimize-sibling-calls。至於如何判斷編譯器是如何做TCO的,請看彙編器輸出(例如gcc -S)或反彙編目標代碼。

1
  1. 優化是編譯器特有的。請查閱文檔以瞭解各種優化標誌
  2. 您也可以在編譯器文檔中找到它。如果你很好奇,你可以編寫一個尾遞歸函數並傳遞一個大的參數,並且監視堆棧溢出。 (如果你理解生成的代碼,檢查生成的彙編程序可能是一個更好的選擇。)
  3. 您只需使用調試器,並查看函數參數/局部變量的地址。如果它們在調試器顯示的每個邏輯幀上增加/減少(或者它實際上只顯示一幀,即使您進行了多次調用),您也會知道TCO是否已完成或未完成。
0

確定是否發生尾呼叫的一種方法是查看是否可以強制堆棧溢出。採用VC++ 2005 Express Edition的下列程序不產生堆棧溢出,並,即使其結果相當迅速地超過長一倍的容量,你可以告訴所有的迭代正在處理時,TCO正在發生的事情:

/* FibTail.c 0.00    UTF-8     dh:2008-11-23 
    * --|----1----|----2----|----3----|----4----|----5----|----6----|----* 
    * 
    * Demonstrate Fibonacci computation by tail call to see whether it is 
    * is eliminated through compiler optimization. 
    */ 

    #include <stdio.h> 


    long double fibcycle(long double f0, long double f1, unsigned i) 
    { /* accumulate successive fib(n-i) values by tail calls */ 

     if (i == 0) return f1; 
     return fibcycle(f1, f0+f1, --i); 
     } 


    long double fib(unsigned n) 
    { /* the basic fib(n) setup and return. */ 
     return fibcycle(1.0, 0.0, n); 
     } 

    int main(int argc, char* argv[ ]) 
    { /* compute some fibs until something breaks */ 

     int i; 

     printf("\n   i       fib(i)\n\n"); 

     for (i = 1; i > 0; i+=i) 
     { /* Do for powers of 2 until i flips negative 
      or stack overflow, whichever comes first */ 
      printf("%12d %30.20LG \n", i, fib((unsigned) i)); 
      } 


     printf("\n\n"); 
     return 0; 
     } 

但是請注意,該簡化,以使fibcycle純尾調用無異於搞清楚一個交互的版本,根本不會做尾調用(並有或無TCO的編譯器工作。

這可能是有趣的,以看TCO如何會發現,是不是已經接近最佳,並通過迭代容易更換的優化實驗。