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

Windows 平台程序執行時間測量完全指南:GetTickCount、timeGetTime、QueryPerformanceCounter 精度對比與選型

     編輯:關於C語言

三大計時 API 對比總覽

API頭文件/庫精度適用場景缺點
GetTickCount()<windows.h>~15.6 ms (系統時鐘中斷周期)粗略耗時統計、超時判斷精度低、49.7 天溢出(GetTickCount64 解決)
timeGetTime()<mmsystem.h> + winmm.lib~1 ms (可通過 timeBeginPeriod 提升)多媒體定時、遊戲循環需鏈接 winmm.lib、全局影響系統調度精度
QueryPerformanceCounter()<windows.h> (Kernel32.lib)~0.1 - 1 微秒 (CPU 時鐘頻率)高精度性能分析、基準測試、遊戲引擎跨 CPU 核心同步問題(現代 CPU 已修復)、需查詢頻率
clock()<time.h>~1 ms (C 標準庫實現,通常基於 GetTickCount 或 QPC)跨平台 CPU 時間統計測量 CPU 時間而非牆鐘時間、多線程下為所有線程 CPU 時間之和

代碼實現範例

1. GetTickCount / GetTickCount64(推薦 64 位版)

#include <windows.h>
DWORD start = GetTickCount();
// 或 ULONGLONG start = GetTickCount64(); // 避免 49.7 天溢出
FunctionUnderTest();
DWORD elapsed = GetTickCount() - start; // 單位:毫秒
printf("Elapsed: %lu ms\n", elapsed);

2. timeGetTime(需 #pragma comment(lib, "winmm.lib"))

#include <windows.h>
#include <mmsystem.h>
#pragma comment(lib, "winmm.lib")

// 可選:提升系統定時器精度至 1ms (影響全系統功耗)
TIMECAPS tc; timeGetDevCaps(&tc, sizeof(tc));
timeBeginPeriod(tc.wPeriodMin); // 最小周期

DWORD start = timeGetTime();
FunctionUnderTest();
DWORD elapsed = timeGetTime() - start;
timeEndPeriod(tc.wPeriodMin); // 恢復

3. QueryPerformanceCounter(高精度黃金標準)

#include <windows.h>

LARGE_INTEGER freq, start, end;
QueryPerformanceFrequency(&freq); // 僅需查詢一次,全程緩存
QueryPerformanceCounter(&start);
FunctionUnderTest();
QueryPerformanceCounter(&end);

double elapsed_ms = (double)(end.QuadPart - start.QuadPart) * 1000.0 / freq.QuadPart;
printf("Elapsed: %.3f ms\n", elapsed_ms);

4. 封裝為 C++ RAII 計時器類(推薦生產代碼風格)


class ScopedTimer {
    LARGE_INTEGER freq_, start_;
    const char* name_;
public:
    ScopedTimer(const char* name) : name_(name) {
        QueryPerformanceFrequency(&freq_);
        QueryPerformanceCounter(&start_);
    }
    ~ScopedTimer() {
        LARGE_INTEGER end; QueryPerformanceCounter(&end);
        double ms = (double)(end.QuadPart - start_.QuadPart) * 1000.0 / freq_.QuadPart;
        printf("[TIMER] %s: %.3f ms\n", name_, ms);
    }
};

// 用法:
void TestFunction() {
    ScopedTimer timer("TestFunction");
    // ... 待測代碼 ...
}
// 函數退出時自動打印耗時

進階避坑指南

  • CPU 變頻影響:現代 CPU 支持 Invariant TSC,QueryPerformanceFrequency 返回固定頻率,不受變頻影響(Win10+ / 近代硬體)。舊系統需檢查 QueryPerformanceFrequency 是否穩定。
  • 多核同步:早期多核系統 TSC 不同步導致跨核測量錯誤。現代 OS (Win7+) 已在 HAL 層修正,QPC 可安全跨核使用。
  • 內聯汇編 RDTSC:極致性能可直接讀取時間戳計數器,但需處理核心遷移、變頻、指令重排,極易出錯,**強烈建議使用 QPC**。
  • 編譯器優化干擾:被測代碼若無副作用可能被優化掉。使用 volatile 變量接收結果、或調用外部函數、或內嵌汇編 asm volatile("" ::: "memory") 防止優化。

總結選型建議

  1. 微秒級精度、性能分析、基準測試:QueryPerformanceCounter 唯一首選。
  2. 毫秒級、簡單超時、跨平台:GetTickCount64(Win)/ clock_gettime(CLOCK_MONOTONIC)(Linux)。
  3. 多媒體/遊戲固定幀率循環:timeGetTime + timeBeginPeriod(1)。
  4. C 標準庫風格、測量 CPU 時間:clock()。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved