Windows 消息機制導致 WM_TIMER/Sleep 精度低(~10-15ms),多媒體定時器 timeSetEvent 達到 1ms 但仍不足工業控制、數據采集等高精度場景。高性能計數器 (QueryPerformanceCounter/QueryPerformanceFrequency) 利用 CPU 時鐘頻率,可達微秒級精度。
BOOL QueryPerformanceFrequency(LARGE_INTEGER* lpFrequency); // 獲取頻率 (計數/秒)
BOOL QueryPerformanceCounter(LARGE_INTEGER* lpCount); // 獲取當前計數值
LARGE_INTEGER 為 64 位整數(或高低 32 位聯合體),VC6 支持 .QuadPart 直接訪問 64 位值。
QueryPerformanceFrequency 獲取頻率 f。t (微秒) 換算為計數增量:delta = f * t / 1,000,000。start,循環調用 QueryPerformanceCounter 直到 current - start >= delta。elapsed = (current - start) * 1,000,000 / f (微秒)。HighTimer。IDC_TEST 目標微秒、IDC_ACTUAL 實際微秒)、兩按鈕 (IDOK 退出、ID_TEST 測試)。DWORD m_dwTest、DWORD m_dwAct;添加 BN_CLICKED 處理 OnTest。// 延時函數:參數為計數增量,返回實際經過計數增量
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); // 顯示到界面
}
QueryPerformanceCounter 可能跨核心讀取不一致(需設置線程親和性)。SetThreadPriority(THREAD_PRIORITY_TIME_CRITICAL)、SetThreadAffinityMask 鎖定單核、內核模式驅動程序定時器。| 方法 | 精度 | 適用場景 |
|---|---|---|
| WM_TIMER / Sleep | ~15ms | UI 刷新、動畫、非關鍵延時 |
| timeGetTime / timeSetEvent | 1ms | 多媒體播放、一般工業控制 |
| GetTickCount 循環 | 1ms | 簡單毫秒級輪詢 |
| QueryPerformanceCounter | 微秒級 | 高精度測量、實時控制、科學計算 |