2013-03-09 76 views
2

比方說,我想基準兩個競爭實現的某些功能double a(double b, double c)。我已經有一個大的array <double, 1000000> vals從中我可以輸入值,所以我的標杆看起來大致是這樣的:如何強制編譯器不跳過我的函數調用?

//start timer here 
double r; 
for (int i = 0; i < 1000000; i+=2) { 
    r = a(vals[i], vals[i+1]); 
} 
//stop timer here 

現在,一個聰明的編譯器可以意識到,我永遠只能使用最後一次迭代的結果,簡單地殺死其餘的,留給我double r = a(vals[999998], vals[999999])。這當然會破壞基準測試的目的。

有沒有一種好的方法(如果它適用於多個編譯器,則可以獲得額外的積分),以防止這種優化,同時保持所有其他優化?我也看到其他線程插入空asm塊,但我擔心可能會阻止內聯或重新排序。我也不是特別喜歡在每次迭代中添加結果sum += r;的想法,因爲這是額外的工作, 對於這個問題,如果我們可以專注於其他替代解決方案,那將是非常好的,但對於任何對此感興趣的人來說,在共識爲+=的意見中有熱烈的討論在許多情況下是最合適的方法。

+0

你爲什麼要這麼做? – 2013-03-09 11:12:13

+0

因爲我有兩個不同的'a'實現,我想比較它們。 – us2012 2013-03-09 11:13:10

+0

重新排序通常是作爲優化afaik完成的。 – 2013-03-09 11:13:26

回答

3

a放在單獨的編譯單元中不是使用LTO(鏈接時優化)。這樣的話:

  • 循環總是相同的(沒有區別,由於基於a優化)
  • 函數調用的開銷總是相同
  • 爲了測量純開銷,並且有一個基準比較實現,只是基準空版本的a

注意,編譯器不能假定調用a有沒有副作用,因此它不能改善循環路程,取代它的機智h只是最後一次通話。


完全不同的方法可以使用RDTSC,它是CPU內核中的一個硬件寄存器,用於測量時鐘週期。它有時對微基準有用,但正確理解結果並不是微不足道的。例如,檢查出this和goggle/search SO以獲取有關RDTSCs的更多信息。

+0

雖然會阻止內聯,不是嗎? – us2012 2013-03-09 11:20:49

+0

是的,因爲沒有LTO,編譯器無法將方法從一個TU內聯到另一個TU。 – 2013-03-09 11:21:58

+0

@ us2012:增加RDTSC,也許這是您的選擇/想法? – 2013-03-09 11:43:05

相關問題