轉自:http://blog.csdn.net/x86/article/details/2235267
在linux開發版最長問到的問題之一就是在linux下如何得到更精確的計時。其實有很多辦法,比如以前就有人用select。不過現在有更精確的實時時鐘可以用,這就是用CLOCK_PROCESS_CPUTIME_ID做參數通過timer_create來創建timer。通過clock_getres可以得到系統的精度。
實際上,上述方法底層用的就是CPU的rdtsc指令。 在linux下,可以用到CPU的rdtsc指令(當然,windows下也是這樣。現在的CPU一般都支持這個指令)來得到一個CPU的時間戳(Time Stamp),這個值是每個指令週期都增加的,再根據CPU的頻率就可以計算出時間來。用這種方式,對於頻率高的CPU,甚至可以實現納秒級的時間控制。不過據說因爲精度太高,這種方式數據抖動比較厲害,每次結果都不一樣,經常有幾百甚至上千的差距。不過在我的實驗中誤差並沒有這麼大,上下在1%左右,不過如果你的要求高的話,這1%也是很厲害的。不過sleep調用也是會有誤差的,這裏就不去研究了。
下面是源碼:
int get_rdtsc() {
asm("rdtsc");
}
int main() {
int i;
for(i=0;i<10;i++) {
int t1 = get_rdtsc();
sleep(1);
int t2 = get_rdtsc();
printf("t2 - t1 = %ld (%ldMHZ) ", t2 - t1, (t2-t1)/1000000);
}
}
我的實驗環境:Intel E6320/2G,使用VMWare虛擬機,系統是centos5-x86。下面是輸出結果。
t2 - t1 = 1865320163 (1865MHZ)
t2 - t1 = 1865996702 (1865MHZ)
t2 - t1 = 1862758710 (1862MHZ)
t2 - t1 = 1865247214 (1865MHZ)
t2 - t1 = 1863456686 (1863MHZ)
t2 - t1 = 1865427930 (1865MHZ)
t2 - t1 = 1865423429 (1865MHZ)
t2 - t1 = 1863616999 (1863MHZ)
t2 - t1 = 1865105795 (1865MHZ)
t2 - t1 = 1867224090 (1867MHZ)
額外的rdtsc實現
- static inline unsigned long long rdtsc(void)
- {
- unsigned hi, lo;
- __asm__ __volatile__ ("rdtsc" : "=a"(lo), "=d"(hi));
- return ( (unsigned long long)lo)|( ((unsigned long long)hi)<<32 );
- }