我知道我必須使用:rdtsc。測量的函數是確定性的,但結果遠不是可重複的(我從運行到運行得到5%的振盪)。 可能的原因是:如何準確測量C++函數使用的時鐘週期?
- 上下文切換
- 緩存未命中
你知道有其他原因? 如何消除它們?
我知道我必須使用:rdtsc。測量的函數是確定性的,但結果遠不是可重複的(我從運行到運行得到5%的振盪)。 可能的原因是:如何準確測量C++函數使用的時鐘週期?
你知道有其他原因? 如何消除它們?
TSC(rdtsc使用)通常在多處理器系統上不同步。它可能有助於設置CPU關聯性,以便將進程綁定到單個CPU。
如果可以的話,您也可以從HPET timers得到時間戳,這些不容易出現同樣的問題。
至於可重複性,這些差異是真實的。您可以禁用緩存,爲進程提供實時優先級,和/或(如果在Linux或類似的環境中)用較低的固定計時器中斷頻率(時間片切片)重新編譯內核。您不能完全消除差異,至少不容易,而不是常規的CPU + OS組合。
一般來說,爲了簡單的編碼,可靠性和便攜性的原因,我建議你使用操作系統所提供的。如果它提供高精度計時器,請使用適當的操作系統幫助程序。 (以防萬一你想對加密系統進行一次時間攻擊,那麼你將不得不忍受1.這種隨機性和2.一般的防禦措施,因爲很好的原因使系統變得不可預測,所以該功能可能不是關於時間的確定性。)
編輯:添加關於定時器操作系統可以提供的段落。
編輯:這是指Linux。爲了將進程綁定到單個CPU(從RDTSC準確讀取),可以使用sched_setaffinity(2)。而here的一些代碼來自我的一個項目,用於其他目的(將線程映射到CPU)。這應該是你的第一次嘗試。至於HPET,只要內核和機器支持這些定時器,就可以使用常規的POSIX調用,如these。
查看問題Is stopwatch benchmarking acceptable?瞭解現代多核多線程多進程機器上微基準測試的方差。
儘管問題是關於Java的,但這些考慮因素適用於任何語言的基準測試。
另見:How do I write a correct micro-benchmark in Java?
ALSE看到:What advice can you give me for writing a meaningful benchmark?
添加到的原因列表:分支預測/錯誤預測(這可以通過用某些芯片復預測緩存上下文切換來實現同樣的預測可能會受到程序的不同輸入的影響,因此兩個不同數據集的時間之間的直接比較可能會略有偏差。
總的來說,減輕所有這些幾乎是不可能的,但有些事情可以做到幫助每一個:
但是,當然,到目前爲止,做這種定時的最好方法是在非常大的數據塊上進行很多次處理,以使由無法控制的事物所引入的可變性最小化。 (它永遠不會被真正擦除。)
如果您正在測量時鐘週期,您爲什麼要消除緩存未命中並從基準中分支出錯預測?這些也會在「野外」發生,所以重要的是要查看整個分佈而不僅僅是最佳情況。 – Tom 2009-02-22 23:45:00
爲什麼要消除它們?聽起來像你已經創造了一個現實的基準。該代碼在野外使用時也會具有相同的可變性。可能更糟,因爲您可能已經消除了磁盤和CPU緩存延遲。使用Jon Skeet的方法,創造條件讓你獲得最好的結果,只會讓你感覺良好,但永遠不可能實現。
如果絕對數字很重要,請計算中位數,而不是平均數。
大多數現代處理器都支持一組顯着的低級硬件性能計數器。 如果你真的想知道答案,包括緩存未命中和上下文切換開銷的實際測量結果,請抓住PAPI (Performance API) toolkit,然後在一些(儘管不是全部)操作系統上安裝一個內核補丁,並且通過一些額外的努力,關閉和運行。
實際上在新的Linux內核中有新的perf子系統。例如:
$ ./perf stat du -s /tmp 94796 /tmp Performance counter stats for 'du -s /tmp': 2.546403 task-clock-msecs # 0.060 CPUs 3 context-switches # 0.001 M/sec 0 CPU-migrations # 0.000 M/sec 166 page-faults # 0.065 M/sec 2434963 cycles # 956.236 M/sec 1798092 instructions # 0.738 IPC 302969 branches # 118.979 M/sec 26197 branch-misses # 8.647 % 23217 cache-references # 9.118 M/sec 4621 cache-misses # 1.815 M/sec 0.042406580 seconds time elapsed
謝謝。如何將進程綁定到一個處理器?你有沒有使用HPET的例子? – 2009-02-06 17:46:20
@ŁukaszLew:我編輯了我的文章並添加了詳細信息。 – 2009-02-07 04:38:49
@ŁukaszLew:澄清了最後一段中的最佳方法和HPET。 – 2009-02-07 04:51:28