首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux 用戶態獲取納秒級時間:clock_gettime 完整使用指南

     編輯:關於C語言

核心 API


#include 

int clock_gettime(clockid_t clk_id, struct timespec *tp);

時鐘類型選擇指南

時鐘 ID語義單調性受系統時間調整影響典型用途
CLOCK_REALTIME系統實時時間 (UTC 1970 起)否是 (NTP/用戶修改會跳變)日誌時間戳、壁鐘時間
CLOCK_MONOTONIC啟動後單調遞增是否測量間隔、超時、性能分析 (推薦)
CLOCK_PROCESS_CPUTIME_ID進程 CPU 時間是否進程級 CPU 消耗分析
CLOCK_THREAD_CPUTIME_ID線程 CPU 時間是否線程級 CPU 消耗分析
CLOCK_MONOTONIC_RAW原始硬體計數器 (Linux 2.6.28+)是否最高精度、無 NTP 平滑調整
CLOCK_BOOTTIME含休眠時間的單調時鐘是否需包含休眠的間隔測量

timespec 結構


struct timespec {
    time_t   tv_sec;   // 秒
    long     tv_nsec;  // 納秒 [0, 999999999]
};

標準測量模板


#include 
#include 
#include 

int main() {
    struct timespec start, end;
    
    // 開始計時
    clock_gettime(CLOCK_MONOTONIC, &start);
    
    // 被測代碼
    printf("Hello, World!\n");
    
    // 結束計時
    clock_gettime(CLOCK_MONOTONIC, &end);
    
    // 計算差值 (納秒)
    long long elapsed_ns = (end.tv_sec - start.tv_sec) * 1000000000LL 
                         + (end.tv_nsec - start.tv_nsec);
    
    printf("Elapsed: %lld ns = %.3f us = %.6f ms\n", 
           elapsed_ns, elapsed_ns / 1e3, elapsed_ns / 1e6);
    
    return 0;
}

編譯鏈接


gcc -o timing timing.c -lrt
# -lrt 鏈接 librt (Real-Time library),舊版 glibc 需要,新版已合入 libc

運行示例


$ ./timing
Hello, World!
Elapsed: 15234 ns = 15.234 us = 0.015234 ms

單次 printf 系統調用開銷約 10-20 微秒 (視終端、緩衝區、調度而定)。

高精度封裝函數


static inline long long now_ns(void) {
    struct timespec ts;
    clock_gettime(CLOCK_MONOTONIC, &ts);
    return (long long)ts.tv_sec * 1000000000LL + ts.tv_nsec;
}

// 使用
long long t1 = now_ns();
// ...
long long t2 = now_ns();
printf("Delta: %lld ns\n", t2 - t1);

常見陷阱

  1. 用 CLOCK_REALTIME 測間隔:系統時間回撥會導致負間隔
  2. tv_nsec 直接相減不借位:end.tv_nsec < start.tv_nsec 時需向 tv_sec 借 1 秒 (1e9 ns)
  3. 忽略編譯器優化移除被測代碼:用 volatile 或內存屏障保留副作用
  4. 頻繁調用開銷:clock_gettime 自身約 20-50ns,極微小代碼段測量時佔比大

進階:RDTSC 指令級計時


static inline unsigned long long rdtsc(void) {
    unsigned int lo, hi;
    __asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
    return ((unsigned long long)hi << 32) | lo;
}

// 需校準 CPU 頻率轉換為納秒,受變頻、睿頻、遷移影響,僅適合極短代碼段相對比較

總結

CLOCK_MONOTONIC + clock_gettime 是 Linux 用戶態測量時間間隔的標準、可移植、高精度方案。納秒級精度滿足絕大多數性能分析、超時控制、基準測試需求。記住:測間隔必用單調時鐘,借位正確計算差值,鏈接 -lrt。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved