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

Visual C++ 實現微秒級高精度定時器:QueryPerformanceCounter 深度應用

     編輯:關於VC++

背景與挑戰

Windows 消息機制導致 WM_TIMER/Sleep 精度低(~10-15ms),多媒體定時器 timeSetEvent 達到 1ms 但仍不足工業控制、數據采集等高精度場景。高性能計數器 (QueryPerformanceCounter/QueryPerformanceFrequency) 利用 CPU 時鐘頻率,可達微秒級精度。

核心 API

BOOL QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency); // 獲取頻率 (計數/秒)
BOOL QueryPerformanceCounter(LARGE_INTEGER* lpCount);       // 獲取當前計數值

LARGE_INTEGER 為 64 位整數(或高低 32 位聯合體),VC6 支持 .QuadPart 直接訪問 64 位值。

精確延時算法原理

  1. 調用 QueryPerformanceFrequency 獲取頻率 f。
  2. 目標延時 t (微秒) 換算為計數增量:delta = f * t / 1,000,000。
  3. 記錄起始計數 start,循環調用 QueryPerformanceCounter 直到 current - start >= delta。
  4. 實際耗時 elapsed = (current - start) * 1,000,000 / f (微秒)。

完整對話框實現

1. 項目創建

  • 基於對話框的 MFC 應用,名稱 HighTimer。
  • 界面:兩個靜態文本、兩個編輯框 (IDC_TEST 目標微秒、IDC_ACTUAL 實際微秒)、兩按鈕 (IDOK 退出、ID_TEST 測試)。
  • ClassWizard 關聯變量:DWORD m_dwTest、DWORD m_dwAct;添加 BN_CLICKED 處理 OnTest。

2. 核心代碼

// 延時函數:參數為計數增量,返回實際經過計數增量
LARGE_INTEGER MySleep(LARGE_INTEGER Interval) {
    LARGE_INTEGER prev, curr, elapsed;
    QueryPerformanceCounter(&prev);
    curr = prev;
    while (curr.QuadPart - prev.QuadPart < Interval.QuadPart) {
        QueryPerformanceCounter(&curr);
    }
    elapsed.QuadPart = curr.QuadPart - prev.QuadPart;
    return elapsed;
}

void CHighTimerDlg::OnTest() {
    UpdateData(TRUE); // 從界面獲取 m_dwTest
    LARGE_INTEGER freq;
    if (!QueryPerformanceFrequency(&freq)) {
        MessageBox(_T("硬件不支持高性能計數器"), _T("不支持"), MB_ICONEXCLAMATION);
        return;
    }
    // 目標微秒換算為計數增量
    LARGE_INTEGER target;
    target.QuadPart = freq.QuadPart * m_dwTest / 1000000;
    // 執行延時
    LARGE_INTEGER actual = MySleep(target);
    // 實際計數換算回微秒
    m_dwAct = (DWORD)(1000000 * actual.QuadPart / freq.QuadPart);
    UpdateData(FALSE); // 顯示到界面
}

精度分析與誤差來源

  • 理論精度取決於 CPU 頻率(如 3GHz → ~0.33ns 分辨率)。
  • 實測誤差通常 <5µs,主要來自:
    1. 循環判斷與函數調用開銷(數十個時鐘週期)。
    2. 系統調度:線程可能被時間片切換出 CPU。
    3. 多核/變頻 CPU:QueryPerformanceCounter 可能跨核心讀取不一致(需設置線程親和性)。
  • 極高精度需求可考慮:SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL)、SetThreadAffinityMask 鎖定單核、內核模式驅動程序定時器。

對比總結

方法精度適用場景
WM_TIMER / Sleep~15msUI 刷新、動畫、非關鍵延時
timeGetTime / timeSetEvent1ms多媒體播放、一般工業控制
GetTickCount 循環1ms簡單毫秒級輪詢
QueryPerformanceCounter微秒級高精度測量、實時控制、科學計算
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved