2014-02-13 29 views
2

我標杆我GaussQuadrature模板類的一部分,通過調用成員函數Quadrature 1M次循環和定時整個循環(如果你知道一個更好的辦法,請讓我知道!)。在此類的預期應用程序中,構造函數將被調用一次,並且該例程將被多次調用,但我試圖在循環內調用構造函數1M次,並在外部調用構造函數以查看哪個更快。創建對象的內/外循環:分配和速度

  1. 如果我把循環內的構造,該構造函數被調用每一次迭代,但它看起來像它的分配到相同的內存空間(注意,下面的代碼片段,還有就是聲明std::cout << "ctor\n";在構造函數中) 。這是巧合還是更深層次?這裏的片段:

    for(int i = 0; i < 1000000; ++i) { 
        GaussQuadrature<double> Q(N, func, a, b); // some arguments 
        Q.Quadrature();   
    
        std::cout << "address: " << &Q << "\n";          
    } 
    

    這給:在

    time: 12.47999954 
    

    ctor 
    address: 0x7fff23059400 
    ctor 
    address: 0x7fff23059400 
    . 
    . 
    . 
    ctor 
    address: 0x7fff23059400 
    

時機這一點沒有在循環或構造的打印語句,即

clock_t tic = clock();  

    for(int i = 0; i < 1000000; ++i) { 
     GaussQuadrature<double> Q(N, func, a, b); 
     Q.Quadrature();           
    } 

    float elapsed = (clock() - (float)tic)/CLOCKS_PER_SEC; 

    std::cout << std::setprecision(10) << "time: " << elapsed << "\n"; 

結果現在3210

  1. ,如果我不是叫外循環的構造,那麼當然它僅調用一次,但它實際上需要更長的時間:

    clock_t tic = clock(); 
    GaussQuadrature<double> Q(N, func, a, b); 
    
    for(int i = 0; i < 1000000; ++i) { 
        Q.Quadrature();         
    } 
    
    float elapsed = (clock() - (float)tic)/CLOCKS_PER_SEC; 
    
    std::cout << std::setprecision(10) << "time: " << elapsed << "\n"; 
    

    這給

    time: 12.65999985 
    

我跑了幾次,結果與時間相似。有什麼想法嗎?謝謝!

回答

2

首先,在進行計時測試時,您需要關閉任何文本輸出,例如printfs和cout。這很重要,因爲通過包括他們,你隱藏了課堂的真實表現。你的測試方法是可以的。一百萬次調用算法是合理的。但請記住緩存內存。根據內存管理器的行爲,可以接收相同的內存指針。最後,我想,在您將文本輸出註釋掉之後,您的第二個實現將比第一個實現更快。

最終建議:您可能更喜歡使用QueryPerformanceFrequency和 QueryPerformanceCounter函數來獲得更精確的計時。

+2

他得到相同的指針,因爲它被分配在堆棧上。每次通過循環時,它都被分配和釋放,並且每次都在堆棧上釋放相同的插槽。 –

+0

是的,我同意你的意見,我不想讓他更困惑:) –

+0

@SemihOzmen我其實沒有打印報表,請看我更新的帖子。任何想法爲什麼它被稱爲1M次而不是一次? – bcf

0

它可能是由編譯器完成的優化的結果。 For循環可以自動「展開」http://en.wikipedia.org/wiki/Loop_unwinding,最小化分支,並且這種展開也可以通過CPU和流水線的內部並行性與某些優勢一起使用。

「如果循環中的語句彼此獨立(即循環中較早出現的語句不影響其後的語句),則語句可能會並行執行。」

嘗試禁用所有優化並再次檢查這些時間。