介绍
供WIN9X使用的高精度定时器:QueryPerformanceFrequency()
和QueryPerformanceCounter()
,要求计算机从硬件上支持高精度定时器。头文件为 windows.h头
。
函数的原形是:
BOOL QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency); // 获取时钟频率
BOOL QueryPerformanceCounter (LARGE_INTEGER *lpCount); // 获取时钟计数值
数据类型LARGE_INTEGER
既可以是一个作为8字节长的整数,也可以是作为两个4字节长的整数的联合结构,其具体用法根据编译器是否支持64位而定。该类型的定义如下:
typedef union _LARGE_INTEGER {
struct {
ULONG LowPart;
LONG HighPart;
} DUMMYSTRUCTNAME;
struct {
ULONG LowPart;
LONG HighPart;
} u;
#endif //MIDL_PASS
LONGLONG QuadPart;
} LARGE_INTEGER;
在定时前应该先调用QueryPerformanceFrequency()
函数获得机器内部计时器的时钟频率。接着在需要严格计时的事件发生前和发生之后分别调用QueryPerformanceCounter()
,利用两次获得的计数之差和时钟频率,就可以计算出事件经历的精确时间。
测试程序
测试Sleep的精确时间:
#include <windows.h>
#include <iostream>
#include <thread>
int main()
{
LARGE_INTEGER freq;
LARGE_INTEGER beginTime;
LARGE_INTEGER endTime;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&beginTime);
std::this_thread::sleep_for(std::chrono::seconds(10));
QueryPerformanceCounter(&endTime);
int timeOfSecond = (double)(endTime.QuadPart - beginTime.QuadPart) / (double)freq.QuadPart;
int timeOfMicroSecond = (double)(endTime.QuadPart - beginTime.QuadPart) * 1e6 / (double)freq.QuadPart;
std::cout << timeOfSecond << " " << timeOfMicroSecond << std::endl;
return 0;
}
一个封装类Timer(来自miloyip)
#include <windows.h>
class Timer {
public:
Timer() : start_(), end_() {
}
void Start() {
QueryPerformanceCounter(&start_);
}
void Stop() {
QueryPerformanceCounter(&end_);
}
double GetElapsedMilliseconds() {
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
return (end_.QuadPart - start_.QuadPart) * 1000.0 / freq.QuadPart;
}
private:
LARGE_INTEGER start_;
LARGE_INTEGER end_;
};