| API/函數 | 平台 | 精度 | 單位 | 適用場景 |
|---|---|---|---|---|
| GetTickCount() | Windows | ~15.6 ms | ms | 粗略計時、長時間運行 |
| timeGetTime() | Windows (winmm.lib) | ~1 ms | ms | 多媒體計時、遊戲迴路 |
| clock() | 標準 C | ~1 ms | clock tick | CPU 時間、跨平台 |
| QueryPerformanceCounter | Windows | ~0.3 µs | 計數器頻率 | 高精度區間測量 |
| gettimeofday() | Linux/Unix | ~1 µs | µs | 跨平台微秒級 |
| clock_gettime(CLOCK_MONOTONIC) | Linux | ~1 ns | ns | 高精度、不受系統時間調整影響 |
| RDTSC 指令 | x86/x64 | 1 CPU 週期 | cycle | 極致微基準測試 |
| std::chrono::high_resolution_clock | C++11 跨平台 | 平台相關 | ns | 現代 C++ 首選 |
#include <windows.h> #include <stdio.h>
DWORD start = GetTickCount();
Sleep(1000); // 模擬工作
DWORD elapsed = GetTickCount() - start;
printf("Elapsed: %lu ms\n", elapsed);
⚠️ 49.7 天溢出,GetTickCount64 解決。
#pragma comment(lib, "winmm.lib")
#include <mmsystem.h>
DWORD start = timeGetTime();
// ... work ...
DWORD elapsed = timeGetTime() - start;
LARGE_INTEGER freq, start, end;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&start);
// ... work ...
QueryPerformanceCounter(&end);
double ms = (double)(end.QuadPart - start.QuadPart) * 1000.0 / freq.QuadPart;
printf("%.3f ms\n", ms);
#include <time.h> #include <stdio.h>
clock_t t = clock();
// ... work ...
t = clock() - t;
printf("CPU time: %.3f s\n", (double)t / CLOCKS_PER_SEC);
注意:多線程下返回所有線程 CPU 時間總和。
#include <chrono> #include <iostream>
using namespace std::chrono;
auto t1 = high_resolution_clock::now();
// ... work ...
auto t2 = high_resolution_clock::now();
auto ms = duration_cast<milliseconds>(t2 - t1).count();
auto us = duration_cast<microseconds>(t2 - t1).count();
auto ns = duration_cast<nanoseconds>(t2 - t1).count();
std::cout << ms << " ms, " << us << " µs, " << ns << " ns\n";
#include <time.h> #include <stdio.h>
struct timespec t1, t2;
clock_gettime(CLOCK_MONOTONIC, &t1);
// ... work ...
clock_gettime(CLOCK_MONOTONIC, &t2);
long ns = (t2.tv_sec - t1.tv_sec) * 1000000000L + (t2.tv_nsec - t1.tv_nsec);
printf("%ld ns (%.3f ms)\n", ns, ns / 1e6);
// GCC/Clang 內建
#include <stdint.h>
static inline uint64_t rdtsc() {
unsigned hi, lo;
__asm__ __volatile__("rdtsc" : "=a"(lo), "=d"(hi));
return ((uint64_t)hi << 32) | lo;
}
// MSVC 內建
#include <intrin.h>
#pragma intrinsic(__rdtsc)
uint64_t start = __rdtsc();
// ... work ...
uint64_t cycles = __rdtsc() - start;
double ms = cycles / (cpu_freq_ghz * 1e6); // 需知 CPU 主頻
⚠️ 陷阱:變頻(SpeedStep/Turbo)、多核遷移、亂序執行、編譯器優化移除代碼。僅用於受控微基準測試。
std::chrono::high_resolution_clock(C++11)或 clock_gettime(CLOCK_MONOTONIC)(C)。QueryPerformanceCounter。timeGetTime(配合 timeBeginPeriod(1) 提升精度)。RDTSC + 固定主頻 + 串行化指令(CPUID)。chrono/QPC/gettimeofday 為牆鐘;clock() 為 CPU 時間。