rdtsc指令返回的是自開機始cpu的週期數,在intel pentium以上級別的cpu中,有乙個稱為「時間戳(time stamp)」的部件,它以64位無符號整型數的格式(高32在edx,低32位在eax),記錄了自cpu上電以來所經過的時鐘週期數。由於目前的cpu主頻都非常高,因此這個部件可以達到 納秒級的計時精度。
多核時代不宜再用 x86 的 rdtsc 指令測試指令週期和時間,原因有三:
具體講解在
rdtsc 一般的用法是,先後執行兩次,記下兩個 64-bit 整數 start 和 end,那麼 end-start 代表了這期間 cpu 的時鐘週期數。
在多核下,這兩次執行可能會在兩個 cpu 上發生,而這兩個 cpu 的計數器的初值不一定相同(由於完成上電復位的準確時機不同),(有辦法同步,見[3]),那麼就導致 micro-benchmarking 的結果包含了這個誤差,這個誤差可正可負,取決於先執行的那塊 cpu 的時鐘計數器是超前還是落後。
另外,對於計時這個用途,時間 = 週期數 / 頻率,由於頻率可能會變(比如我的筆記本的 cpu 通常半速執行在 800mhz,繁忙的時候全速執行在 1.6ghz),那麼測得的時間也就不準確了。有的新 cpu 的 rdtsc 計數頻率是恆定的,那麼時鐘是準了,那又會導致 micro-benchmarking 的結果不准,見 [2]。還有乙個可能是掉電之後恢復(比如休眠),那麼 tsc 會清零。 總之,用 rdtsc 來計時是不靈的。
雖然 rdtsc 廢掉了,效能測試用的高精度計時還是有辦法的 [2],在 windows 用 queryperformancecounter 和 queryperformancefrequency,linux 下用 posix 的 clock_gettime 函式,以 clock_monotonic 引數呼叫。或者按文獻 [3] 的辦法,先同步 tsc, 再使用它。(我不知道現在最新的 linux 官方核心是不是內建了這個同步演算法。也不清楚校準後的兩個 cpu 的「鐘」會不會再次失步。)
[1]
[2]
[3] x86: unify/rewrite smp tsc sync code
//linux下測試**
#include
#include
#include
#define times 100
#define size 1024
__u64 rdtsc()
int myfunction()
else
}return0;}
int test_rdtsc()
int main()
執行結果如下
root@libin:~/program/assembly/rdtsc# ./test
myfunction cost 310949 cpu cycles
檢測時間戳
做簽到,倒計時時常用的幾個方法,記錄一下。檢測兩個時間是否是同一天 private bool isoneday datetime t1,datetime t2 檢測自傳入時間起還差多久滿24小時 private double checktimetoday datetime time 將傳入的秒數轉換...
C 統計精確時間
queryperformancefrequency用法 queryperformancefrequency 基本介紹 型別 win32api 原型 bool queryperformancefrequency large integer lpfrequency 作用 返回硬體支援的高精度計數器的頻率...
C 中獲取精確時間
程式中獲取精確的時間,有時是非常必要的。常用的是,在測試程式的效能時,需要使用到精確的時間計時。或者其他情況要用到精確的時間。這就要用到乙個函式queryperformancecounter 用法是從第一次呼叫queryperformancecounter 過一段時間後再次呼叫該函式結束的.兩者之差...