2013-01-13 73 views
3

我正在閱讀0123,論文,由lmbench的創建者和源代碼一起瀏覽代碼。BENCH_INNER:lmbench3.0 src代碼宏查詢

  1. 的紙可以下載@卡爾Staelin和拉里·麥沃伊

的BENCH_INNER內()宏撰寫MHz : Anatomy of a Microbenchmark

  • 源代碼lmbench-3.0我有一個疑問:

    #define BENCH_INNER(loop_body, enough) {    \ 
        static iter_t __iterations = 1;    \ 
        int  __enough = get_enough(enough);   \ 
        iter_t  __n;      \ 
        double  __result = 0.;     \ 
                \ 
        while(__result < 0.95 * __enough) {    \ 
         start(0);      \ 
         for (__n = __iterations; __n > 0; __n--) {  \ 
          loop_body;     \ 
         }       \ 
         __result = stop(0,0);     \ 
         if (__result < 0.99 * __enough    \ 
          || __result > 1.2 * __enough) {   \ 
          if (__result > 150.) {    \ 
           double tmp = __iterations/__result; \ 
           tmp *= 1.1 * __enough;   \ 
           __iterations = (iter_t)(tmp + 1); \ 
          } else {     \ 
           if (__iterations > (iter_t)1<<27) { \ 
            __result = 0.;   \ 
            break;    \ 
           }     \ 
           __iterations <<= 3;   \ 
          }      \ 
         }       \ 
        } /* while */       \ 
        save_n((uint64)__iterations); settime((uint64)__result); \ 
    } 
    
    1. 根據我的理解,BENCH_INNER用於自動計算('足夠')的最佳迭代次數。循環執行直到我們繼續迭代一段代碼「loop_body」,這段代碼至少需要95%的選定時間間隔,範圍從5ms到1秒。

    2. 爲了簡單起見,讓我們來「足夠的」是10000微秒

    3. 我們開始與__iterations = 1
    4. 說隨着時間的推移,我們達到了一個階段,__result> 1.2 *「夠了」,即__result> 12000微秒
    5. 現在既然__result> 150微秒,我們繼續前進,規模__iterations的值,使得__result將大約等於1.1 *「足夠的」
    6. 但在此之前,我們可以重新計算__result,我們將打破循環,因爲較早的__result> .95 *'夠'
    7. 我們繼續前進,保存__result的價值和修正值__iterations(這裏__result的值不爲我們節省__iterations)

    不應該在這樣的情況下重新計算__result的代碼?我錯過了一些基本的東西?

  • +0

    你能想出(迭代序列,結果)最終在那種情況下而不是假設? – auselen

    +0

    @auselen - 從代碼邏輯中不明顯嗎?這不是一個假設:邏輯恰好在我們面前。我們肯定可以看到迭代計數被修改,並且我們沒有重新計算結果 –

    +0

    讀取函數並查看輸入輸出空間關係非常困難。人們寫測試是有原因的。 – auselen

    回答

    6

    是的,這裏有一個問題,__result必須設置爲零。

    而且我可以在代碼中看到另一個可能的問題 - 結果是在一種情況下與0.99*enough進行比較,在其他情況下與0.95*enough進行比較,這是高度可疑的錯字。我建議你重寫這個宏,明確說明「令人滿意」的條件並簡化邏輯,首先檢查良好的條件。就像這樣:

    #define SEARCH_EXIT_CASE(__result, __enough) ((__result) > 0.95 * (__enough) && (__result) < 1.2 * (__enough)) 
    
    #define BENCH_INNER(loop_body, enough) {    \ 
        static iter_t __iterations = 1;    \ 
        int  __enough = get_enough(enough);   \ 
        iter_t  __n;      \ 
        double  __result = 0.;     \ 
                \ 
        while(!SEARCH_EXIT_CASE(__result, __enough)) {    \ 
         start(0);      \ 
         for (__n = __iterations; __n > 0; __n--) {  \ 
          loop_body;     \ 
         }       \ 
         __result = stop(0,0);     \ 
         /* good result */ \ 
         if (SEARCH_EXIT_CASE(__result, __enough)) {   \ 
          break; \ 
         } \ 
         /* failure cases */ \ 
         if (__result > 150.) {    \ 
          double tmp = __iterations/__result; \ 
          tmp *= 1.1 * __enough;   \ 
          __iterations = (iter_t)(tmp + 1); \ 
         } else { \ 
          if (__iterations > (iter_t)1<<27) { \ 
           __result = 0.;   \ 
           break;    \ 
          }     \ 
          __iterations <<= 3;   \ 
         } \ 
         __result = 0.;   \ 
        } /* while */       \ 
        save_n((uint64)__iterations); settime((uint64)__result); \ 
    } 
    

    此外,我建議這樣定義1<<27, 1.1, 3, 150.0其他神奇的常量有像MAX_ITERCORRECTION_RATEINCREASE_RATERESULT_OVERFLOW等有意義的名字......

    +0

    我認爲這很好回答 –

    +0

    @Konstantin - 感謝您花時間瀏覽邏輯。不過,讓我補充一點,這不是我的邏輯。我粘貼了來自lmbench實用程序的現有代碼。是的,我同意你的評論,因爲我面臨很多問題,試圖通過硬編碼來理解邏輯 –