linux中獲取當前時間、統計程序運行時間,可以使用gettimeofday()得到毫秒級的時間統計,利用rdtsc指令獲取納秒級時間統計。
gettimeofday()
它是一個linux C庫函數,封裝了系統調用sys_gettimeofday(),在X86_64系統中,該函數是調用vsyscall()來訪問內核數據,而在X386系統上是系統調用syscall。
syscall與vsyscall的區別,只有gettimeofday、time、getcpu這幾個linux C庫函數的系統調用時vsyscall,其余都是syscall。
該函數的時間開銷分析:
syscall系統調用實現:用戶態在syscall中通過軟中斷陷入內核,cpu要做的工作有,用戶態切換到內核態、處理軟中斷、保存寄存器值、復制用戶態參數到內核態、執行、內核態切換回用戶態,這些處理過程是超過1ms的。
vsyscall系統調用實現:在內核態創建一個共享內存,用戶態也可以訪問,並不用發送中斷,優點:速度快,成本低;
rdtsc指令
rdtsc指令是X86平台的讀取時間戳寄存器TSC(64位)的指令,TSC寄存器統計了CPU自啟動以來的運行時間,每個時鍾信號到來時,TSC遞增1。
目前CPU的主頻>1GHZ,故時鍾周期是納秒級別的。
64位寄存器的溢出時間計算:若CPU主頻是3GHZ,1s內TSC增加了3000000000,64bit寄存器溢出需要的時間:2^64/3*10^9=6148914691.2s=194年,故一般不會溢出的。
利用rdtsc獲取系統納秒級時間統計的示例代碼如下(i386系統):
1 void getCurrTime(uint64_t& now) 2 { 3 uint32_t lval, hval; 4 asm volatile ("rdtsc" : "=a" (lval), "=d" (hval)); 5 now = hval; 6 now = (now << 32) | lval; 7 }