2013-07-25 88 views
3

我想基準一個C/C++代碼。我想測量cpu時間,壁掛時間和週期/字節。我寫了一些測量函數,但是在週期/字節上有問題。基準代碼 - 我做對了嗎?

要獲得CPU時間我寫了一個函數getrusage()RUSAGE_SELF,牆體時間我使用clock_gettimeMONOTONIC,獲得週期/字節我用rdtsc

我處理的輸入緩衝區的大小,例如1024:char buffer[1024]。我怎麼基準:

  1. 做一個預熱階段,只需撥打fun2measure(args) 1000次:

for(int i=0; i<1000; i++) fun2measure(args);

  1. 然後,做一個真正的定時基準,爲掛鐘時間:

    `unsigned long i; 雙倍拍攝; double timeTotal = 3.0; //處理3秒

    for(timeTaken =(double)0,i = 0; timeTaken < = timeTotal; timeTaken = walltime(1),i ++) fun2measure(args); `

  2. 而且CPU時間(幾乎相同):

    for (timeTaken=(double)0, i=0; timeTaken <= timeTotal; timeTaken = walltime(1), i++) fun2measure(args);

但是,當我想要得到功能的CPU週期數,我使用這段代碼:

`unsigned long s = cyclecount(); 
    for (timeTaken=(double)0, i=0; timeTaken <= timeTotal; timeTaken = walltime(1), i++) 
    { 
     fun2measure(args); 
    } 
    unsigned long e = cyclecount(); 

unsigned long s = cyclecount(); 
    for (timeTaken=(double)0, i=0; timeTaken <= timeTotal; timeTaken = cputime(1), i++) 
    { 
     fun2measure(args); 
    } 
    unsigned long e = cyclecount();` 

然後計數週期/字節:((e - s)/(i * inputsSize);。這裏inputsSize是1024,因爲它的長度爲buffer。但是,當我升到totalTime爲10秒我GE奇怪的結果:

10秒:

Did fun2measure 1148531 times in 10.00 seconds for 1024 bytes, 0 cycles/byte [CPU] 
Did fun2measure 1000221 times in 10.00 seconds for 1024 bytes, 3.000000 cycles/byte [WALL] 

5秒:

Did fun2measure 578476 times in 5.00 seconds for 1024 bytes, 0 cycles/byte [CPU] 
Did fun2measure 499542 times in 5.00 seconds for 1024 bytes, 7.000000 cycles/byte [WALL] 

4秒:

Did fun2measure 456828 times in 4.00 seconds for 1024 bytes, 4 cycles/byte [CPU] 
Did fun2measure 396612 times in 4.00 seconds for 1024 bytes, 3.000000 cycles/byte [WALL] 

我的問題:

  1. 這些結果是否正常?
  2. 爲什麼當我增加時間我總是得到0循環/字節在CPU?
  3. 如何測量此類基準測試的平均時間,平均值,標準差等統計數據?
  4. 我的基準測試方法100%可以嗎?

CHEERS!

1日編輯:

Did fun2measure 1138164.00 times in 10.00 seconds for 1024 bytes, 0.410739 cycles/byte [CPU] 
Did fun2measure 999849.00 times in 10.00 seconds for 1024 bytes, 3.382036 cycles/byte [WALL] 

我的結果似乎是確定:

改變idouble後。所以問題#2不再是一個問題了:)

+0

當你計算週期/字節時要小心使用浮點除法 –

+0

@VaughnCato:爲什麼?我應該用'i = 1'嗎?你的意思是我可能在這裏處理'零分割錯誤'? – nullpointer

+0

如果您不使用浮點除法,那麼小於1的值將舍入爲零。 –

回答

1

您的cyclecount基準是有缺陷的,因爲它包括walltime/cputime函數調用的成本。一般來說,我強烈建議你使用合適的分析器,而不是試圖重新發明輪子。尤其是性能計數器會給你你可以信賴的數字。還要注意,由於CPU通常不以固定頻率運行,或者內核可能會執行任務切換並暫停應用一段時間,所以週期非常不可靠。

我個人編寫基準測試程序,使它們運行給定的函數N次,因爲N足夠大,以至於您獲得足夠的樣本。從外表上看,我應用了諸如linux perf這樣的分析器來讓我得出一些難以理解的數據。重複給定時間的基準,然後可以計算stddev/avg值,您可以在幾次運行基準的腳本中執行該操作,並評估分析器的輸出。

+0

好的,但我可以如何stddev /平均值?一點小費? – nullpointer

+0

你的問題到底是什麼?這些值的公式可以在Wikipedia上找到。只需運行N次基準並收集所有值。然後在相應的公式中輸入這些值... – milianw