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

程序運行時間測量方法大全:從毫秒到 CPU 週期級精度

     編輯:關於C語言

方法對比總覽

API/函數平台精度單位適用場景
GetTickCount()Windows~15.6 msms粗略計時、長時間運行
timeGetTime()Windows (winmm.lib)~1 msms多媒體計時、遊戲迴路
clock()標準 C~1 msclock tickCPU 時間、跨平台
QueryPerformanceCounterWindows~0.3 µs計數器頻率高精度區間測量
gettimeofday()Linux/Unix~1 µsµs跨平台微秒級
clock_gettime(CLOCK_MONOTONIC)Linux~1 nsns高精度、不受系統時間調整影響
RDTSC 指令x86/x641 CPU 週期cycle極致微基準測試
std::chrono::high_resolution_clockC++11 跨平台平台相關ns現代 C++ 首選

Windows 經典 API 示例

1. GetTickCount(最簡單)

#include <windows.h> #include <stdio.h>
DWORD start = GetTickCount();
Sleep(1000); // 模擬工作
DWORD elapsed = GetTickCount() - start;
printf("Elapsed: %lu ms\n", elapsed);

⚠️ 49.7 天溢出,GetTickCount64 解決。

2. timeGetTime(需鏈接 winmm.lib)

#pragma comment(lib, "winmm.lib")
#include <mmsystem.h>
DWORD start = timeGetTime();
// ... work ...
DWORD elapsed = timeGetTime() - start;

3. QueryPerformanceCounter(高精度標準)

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);

標準 C/C++ 跨平台方案

4. clock()(測 CPU 時間)

#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 時間總和。

5. C++11 std::chrono(現代首選)

#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";

Linux 高精度 API

6. clock_gettime(纳秒級,單調時鐘)

#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);

極致:RDTSC 讀取 CPU 週期計數器

// 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)、多核遷移、亂序執行、編譯器優化移除代碼。僅用於受控微基準測試。

選型建議

  1. **日常開發/跨平台**:std::chrono::high_resolution_clock(C++11)或 clock_gettime(CLOCK_MONOTONIC)(C)。
  2. **Windows 獨有/舊代碼維護**:QueryPerformanceCounter。
  3. **多媒體/遊戲主迴路**:timeGetTime(配合 timeBeginPeriod(1) 提升精度)。
  4. **CPU 熱點分析/微基準**:RDTSC + 固定主頻 + 串行化指令(CPUID)。
  5. **測量「牆鐘時間」還是「CPU 時間」**:chrono/QPC/gettimeofday 為牆鐘;clock() 為 CPU 時間。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved