#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 | 含休眠時間的單調時鐘 | 是 | 否 | 需包含休眠的間隔測量 |
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);
end.tv_nsec < start.tv_nsec 時需向 tv_sec 借 1 秒 (1e9 ns)volatile 或內存屏障保留副作用clock_gettime 自身約 20-50ns,極微小代碼段測量時佔比大
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。