2009-02-03 100 views

回答

5

TSC(rdtsc使用)通常在多處理器系統上不同步。它可能有助於設置CPU關聯性,以便將進程綁定到單個CPU。

如果可以的話,您也可以從HPET timers得到時間戳,這些不容易出現同樣的問題。

至於可重複性,這些差異是真實的。您可以禁用緩存,爲進程提供實時優先級,和/或(如果在Linux或類似的環境中)用較低的固定計時器中斷頻率(時間片切片)重新編譯內核。您不能完全消除差異,至少不容易,而不是常規的CPU + OS組合。

一般來說,爲了簡單的編碼,可靠性和便攜性的原因,我建議你使用操作系統所提供的。如果它提供高精度計時器,請使用適當的操作系統幫助程序。 (以防萬一你想對加密系統進行一次時間攻擊,那麼你將不得不忍受1.這種隨機性和2.一般的防禦措施,因爲很好的原因使系統變得不可預測,所以該功能可能不是關於時間的確定性。)

編輯:添加關於定時器操作系統可以提供的段落。

編輯:這是指Linux。爲了將進程綁定到單個CPU(從RDTSC準確讀取),可以使用sched_setaffinity(2)。而here的一些代碼來自我的一個項目,用於其他目的(將線程映射到CPU)。這應該是你的第一次嘗試。至於HPET,只要內核和機器支持這些定時器,就可以使用常規的POSIX調用,如these

+0

謝謝。如何將進程綁定到一個處理器?你有沒有使用HPET的例子? – 2009-02-06 17:46:20

+0

@ŁukaszLew:我編輯了我的文章並添加了詳細信息。 – 2009-02-07 04:38:49

+0

@ŁukaszLew:澄清了最後一段中的最佳方法和HPET。 – 2009-02-07 04:51:28

1

添加到的原因列表:分支預測/錯誤預測(這可以通過用某些芯片復預測緩存上下文切換來實現同樣的預測可能會受到程序的不同輸入的影響,因此兩個不同數據集的時間之間的直接比較可能會略有偏差。

總的來說,減輕所有這些幾乎是不可能的,但有些事情可以做到幫助每一個:

  • 緩存小姐:「總理」開始時期之前的高速緩存。不要忘記還有一個指令緩存也需要啓動。對於小型數據集,只需運行一次完整的測試,無需計時,然後再次運行。對於大數據集,執行此操作,然後使用處理器的預緩存指令將第一個數據塊加載回緩存。
  • 上下文切換:在輕載系統上使用多處理器/內核芯片,並將進程的親和性設置爲特定的CPU(最好不是CPU 0)。這也有助於緩存未命中(因爲移動CPU意味着緩存完全丟失)和分支預測(因爲它實際上是一種緩存形式)。

但是,當然,到目前爲止,做這種定時的最好方法是在非常大的數據塊上進行很多次處理,以使由無法控制的事物所引入的可變性最小化。 (它永遠不會被真正擦除。)

+0

如果您正在測量時鐘週期,您爲什麼要消除緩存未命中並從基準中分支出錯預測?這些也會在「野外」發生,所以重要的是要查看整個分佈而不僅僅是最佳情況。 – Tom 2009-02-22 23:45:00

2

爲什麼要消除它們?聽起來像你已經創造了一個現實的基準。該代碼在野外使用時也會具有相同的可變性。可能更糟,因爲您可能已經消除了磁盤和CPU緩存延遲。使用Jon Skeet的方法,創造條件讓你獲得最好的結果,只會讓你感覺良好,但永遠不可能實現。

如果絕對數字很重要,請計算中位數,而不是平均數。

0

大多數現代處理器都支持一組顯着的低級硬件性能計數器。 如果你真的想知道答案,包括緩存未命中和上下文切換開銷的實際測量結果,請抓住PAPI (Performance API) toolkit,然後在一些(儘管不是全部)操作系統上安裝一個內核補丁,並且通過一些額外的努力,關閉和運行。

2

實際上在新的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