admin管理员组

文章数量:1516870

QueryPerformanceCounter计算时间

QueryPerformanceCounter()这个函数返回高精确度性能计数器的值,它可以以微妙为单位计时.

计算时间的公式:

double time=(nStopCounter.QuadPart-nStartCounter.QuadPart)/frequency.QuadPart

这两个函数是VC提供的仅供Windows 95及其后续版本使用的精确时间函数,并要求计算机从硬件上支持精确定时器。
QueryPerformanceFrequency()函数和QueryPerformanceCounter()函数的原型如下:

       BOOL  QueryPerformanceFrequency(LARGE_INTEGER *lpFrequency);
       BOOL  QueryPerformanceCounter(LARGE_INTEGER *lpCount);

数据类型ARGE_INTEGER既可以是一个8字节长的整型数,也可以是两个4字节长的整型数的联合结构, 其具体用法根据编译器是否支持64位而定。该类型的定义如下:

typedef union _LARGE_INTEGER {struct {DWORD LowPart;LONG HighPart;} DUMMYSTRUCTNAME;struct {DWORD LowPart;LONG HighPart;} u;LONGLONG QuadPart;
} LARGE_INTEGER;
#endif //MIDL_PASS

在进行定时之前,先调用QueryPerformanceFrequency()函数获得机器内部定时器的时钟频率, 然后在需要严格定时的事件发生之前和发生之后分别调用QueryPerformanceCounter()函数,利用两次获得的计数之差及时钟频率,计算出事件经历的精确时间。下列代码实现1ms的精确定时:

       LARGE_INTEGER litmp; LONGLONG QPart1,QPart2;double dfMinus, dfFreq, dfTim; QueryPerformanceFrequency(&litmp);dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率QueryPerformanceCounter(&litmp);QPart1 = litmp.QuadPart;// 获得初始值do{QueryPerformanceCounter(&litmp);QPart2 = litmp.QuadPart;//获得中止值dfMinus = (double)(QPart2-QPart1);if(dfMinus<0)dfMinus+=0xffffffffffffffff; //溢出判断dfTim =1000*dfMinus / dfFreq; // 获得对应的时间值,单位为ms}while(dfTim<0.001);

另一个例子

/** QueryPerformanceCounter的精度为us级
**测试过可以精确到微秒级别
**/const unsigned long SLEEP_TIME_MILL = 1000;void calcByQueryPerformanceCounter() {LARGE_INTEGER frequency, startCount, stopCount;WINBOOL ret;//返回性能计数器每秒滴答的个数ret = QueryPerformanceFrequency(&frequency);if(ret) {ret = QueryPerformanceCounter(&startCount);}Sleep(SLEEP_TIME_MILL);if(ret) {QueryPerformanceCounter(&stopCount);}if(ret) {LONGLONG elapsed = (stopCount.QuadPart - startCount.QuadPart) * 1000000 / frequency.QuadPart;qDebug()<<"QueryPerformanceFrequency & QueryPerformanceCounter ="<<elapsed<<"us";}}

 

参考:

 

 


 

本文标签: QueryPerformanceCounter计算时间