精确获取时间(QueryPerformanceCounter)测试程序效率

摘要:
此类型的定义如下:typedefinion_LARGE_INTEGER{structure{DWORDLowPart;//4字节整数LONGHighPart;//4字节整数};LONGLONGQuad零件;//8字节整数}LARGE_integer;在计时之前,调用QueryPerformanceFrequency()函数以获取计算机内部计时器的时钟频率,然后在需要严格计时的事件前后调用QueryPerformanceCounter()函数。使用两个计数和时钟频率之间的差值来计算事件的确切时间。
LARGE_INTEGER tima,timb;
QueryPerformanceCounter(&tima);

http://blog.csdn.net/lsmdiao0812/article/details/3173374

在 Windows Server 2003 和 WindowsXP 中使用 QueryPerformanceCounter 函数的程序可能执行不当

QueryPerformanceCounter 來精確計算執行時間
QueryPerformanceCounter 來精確計算執行時間
// 這個程式展示了如何使用QueryPerformanceCounter 來精確計算執行時間
//代码


 

  1. LARGE_INTEGER m_liPerfFreq={0};
  2.  //获取每秒多少CPU Performance Tick
  3.  QueryPerformanceFrequency(&m_liPerfFreq); 
  4.  LARGE_INTEGER m_liPerfStart={0};
  5.  QueryPerformanceCounter(&m_liPerfStart);
  6.  for(int i=0; i< 100; i++)
  7.   cout << i << endl;
  8.  LARGE_INTEGER liPerfNow={0};
  9.  // 计算CPU运行到现在的时间
  10.  QueryPerformanceCounter(&liPerfNow);
  11.  int time=( ((liPerfNow.QuadPart - m_liPerfStart.QuadPart) * 1000)/m_liPerfFreq.QuadPart);
  12.  char buffer[100];
  13.  sprintf(buffer,"執行時間 %d millisecond ",time);
  14.  cout<<buffer<<endl;

QueryPerformanceCounter()这个函数返回高精确度性能计数器的值,它可以以微妙为单位计时.但是QueryPerformanceCounter()确切的精确计时的最小单位是与系统有关的,所以,必须要查询系统以得到QueryPerformanceCounter()返回的嘀哒声的频率.
QueryPerformanceFrequency()提供了这个频率值,返回每秒嘀哒声的个数.
计算确切的时间是从第一次调用QueryPerformanceCounter()开始的
假设得到的LARGE_INTEGER为nStartCounter,过一段时间后再次调用该函数结束的,
设得到nStopCounter.
两者之差除以QueryPerformanceFrequency()的频率就是开始到结束之间的秒数.由于计时函数本身要耗费很少的时间,要减去一个很少的时间开销.但一般都把这个开销忽略.公式如下:   
                         nStopCounter-nStartCounter
ElapsedTime=------------------------------------ - overhead
frequency

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 ;// 4字节整型数
              LONG  HighPart;// 4字节整型数
           };
           LONGLONG QuadPart ;// 8字节整型数
           
        }LARGE_INTEGER ;

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

 
  1.        LARGE_INTEGER litmp; 
  2.        LONGLONG QPart1,QPart2;
  3.        double dfMinus, dfFreq, dfTim; 
  4.        QueryPerformanceFrequency(&litmp);
  5.        dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
  6.        QueryPerformanceCounter(&litmp);
  7.        QPart1 = litmp.QuadPart;// 获得初始值
  8.        do
  9.        {
  10.           QueryPerformanceCounter(&litmp);
  11.           QPart2 = litmp.QuadPart;//获得中止值
  12.           dfMinus = (double)(QPart2-QPart1);
  13.           dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒
  14.        }while(dfTim<0.001);

  其定时误差不超过1微秒,精度与CPU等机器配置有关。 下面的程序用来测试函数Sleep(100)的精确持续时间:

 
  1.        LARGE_INTEGER litmp; 
  2.        LONGLONG QPart1,QPart2;
  3.        double dfMinus, dfFreq, dfTim; 
  4.        QueryPerformanceFrequency(&litmp);
  5.        dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
  6.        QueryPerformanceCounter(&litmp);
  7.        QPart1 = litmp.QuadPart;// 获得初始值
  8.        Sleep(100);
  9.        QueryPerformanceCounter(&litmp);
  10.        QPart2 = litmp.QuadPart;//获得中止值
  11.        dfMinus = (double)(QPart2-QPart1);
  12.        dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒    

  由于Sleep()函数自身的误差,上述程序每次执行的结果都会有微小误差。下列代码实现1微秒的精确定时:

 
  1.        LARGE_INTEGER litmp; 
  2.        LONGLONG QPart1,QPart2;
  3.        double dfMinus, dfFreq, dfTim; 
  4.        QueryPerformanceFrequency(&litmp);
  5.        dfFreq = (double)litmp.QuadPart;// 获得计数器的时钟频率
  6.        QueryPerformanceCounter(&litmp);
  7.        QPart1 = litmp.QuadPart;// 获得初始值
  8.        do
  9.        {
  10.           QueryPerformanceCounter(&litmp);
  11.           QPart2 = litmp.QuadPart;//获得中止值
  12.           dfMinus = (double)(QPart2-QPart1);
  13.           dfTim = dfMinus / dfFreq;// 获得对应的时间值,单位为秒
  14.        }while(dfTim<0.000001);

其定时误差一般不超过0.5微秒,精度与CPU等机器配置有关。(

免责声明:文章转载自《精确获取时间(QueryPerformanceCounter)测试程序效率》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇WebService基础入门(转)Git Server和sourceTree客户端使用说明下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

Cortex-A15架构解析:它为什么这么强(转)

今年的新手机趋势无异是全面向四核靠拢,不过同样是四核,在实际的性能上其实是千差万别。例如针对入门级主流市场的四核手机普遍采用的都是Cortex-A7以及 Cortex-A9 级别的CPU内核,这类内核性能、成本以及发热都会较低,因此在入门市场上大行其道。  而在高端智能手机中则出现了一些新的变化,除了去年就已经崭露头角的高通Krait系列架构四核外,ARM正...

自己封装的Socket组件,实现服务端多进程共享Socket对象,协同处理客户端请求

自己封装的Socket组件,实现服务端多进程共享Socket对象,协同处理客户端请求 DotNet.Net.MySocket是SLB.NET(Server Load Balance服务器负载均衡)项目中的核心组件。 在实际的项目中发现,单进程的服务端处理高并发的客户请求能力有限。 所以一直在考虑能不能象IIS Web园一样,多个进程提供一个服务,协同处理客...

程序员应知——团队精神

    大家都知道,现在的软件开发已经不再是20年前个人英雄主义的时代,一个超级程序员就能够搞定一切的情况已经很少存在了。更多的情况是我们都是以团队的形式进行系统的设计和开发,因此,团队精神也变得越来越重要。     早在我刚刚毕业要踏入到软件开发这个行业的时候,就在自己的简历里面写到:具有很强的团队精神。然而,说句实话,当时对这个词的理解真的不是那么透彻...

c++程序中写测试log到文件的简单实现

1、int WriteToLog(char* str) { FILE* log; log = fopen("D:\\testlog.txt", "a+"); if (log == NULL){ //OutputDebugString("Log file open failed."); return -1; } fprintf(log, "%s...

GCC高级测试功能扩展——程序性能测试工具gprof、程序覆盖测试工具gcov

gprof是GNU组织下的一个比较有用的性能测试功能:   主要功能:   找出应用程序中消耗CPU时间最多的函数;         产生程序运行时的函数调用关系、调用次数   基本原理:   首先用户要使用gprof工具,必须在GCC编译该文件的选项中添加-pg选项,然后GCC会在用户应用程序的每一个函数中加入一个名为mcount(或者是_mcount、...

软件测试理论1

软件测试理论知识点 第一天 1、按是否查看程序内部结构分为:(1)黑盒测试(black-box testing):只关心输入和输出的结果(2)白盒测试(white-box testing):去研究里面的源代码和程序结构2、按是否运行程序分为:(1)静态测试(static testing):是指不实际运行被测软件,而只是静态地检查程序代码、界面或文档可能存在...