C++高精度实现计算程序运行时间-阿里云开发者社区

开发者社区> 开发与运维> 正文
登录阅读全文

C++高精度实现计算程序运行时间

简介: //C++高精度实现计算程序运行时间#include      #include      using namespace std;        void Test()//测试程序   {        for(int i=0; i

//C++高精度实现计算程序运行时间
#include <iostream>    
#include <windows.h>    
using namespace std;    
  
void Test()//测试程序  
{   
    for(int i=0; i<1000; i++)   
    {      
        for(int j=0; j<100; j++)   
        {   
            printf("%d,%d\n",i,j);   
        }      
    }   
}   
  
int main(void)    
{    
    LARGE_INTEGER BegainTime ;    
    LARGE_INTEGER EndTime ;    
    LARGE_INTEGER Frequency ;    
    QueryPerformanceFrequency(&Frequency);    
    QueryPerformanceCounter(&BegainTime) ;    
  
    //要测试的代码放在这里   
    Test();   
  
    QueryPerformanceCounter(&EndTime);   
  
    //输出运行时间(单位:s)   
    cout << "运行时间(单位:s):" <<(double)( EndTime.QuadPart - BegainTime.QuadPart )/ Frequency.QuadPart <<endl;    
  
    system("pause") ;    
    return 0 ;    
}

 

 

 

附 vc计算高精度时间差

 

 

面线框里的代码便可实现计算精度达到微秒级的时间差:

------------------------------------------------------------------------------------

LARGE_INTEGER litmp;
LONGLONG QPart1,Qpart2;
double dfMinus,dfFreq,dfTime;

//获得计时器的时钟频率
QueryPerformanceFrequency(&litmp);
dfFreq = (double)litmp.QuadPart;
QueryPerformanceCounter(&litmp);
Qpart1 = litmp.QuadPart; //开始计时

Block1(); //工作模块 函数等,根据自己需要添加。

QueryPerformanceCounter(&litmp);
Qpart2 = litmp.QuadPart; //终止计时
dfMinus = (double)(QPart2 - QPart1);//计算计数器值
dfTime = dfMinus / dfFreq;//获得对应时间,单位为秒 你可以乘1000000精确到毫秒级(us)

--------------------------------------------------------------------------------------

在一些计算机硬件系统中,包含有高精度运行计数器(high-resolution   performance  
counter),利用它可以获得高精度定时间隔,其精度与CPU的时钟频率有关。  
   
1、首先调用QueryPerformanceFrequency函数取得高精度运行计数器的频率f。单位是每秒多少次(n/s),此数  
一般很大。  
2、在需要定时的代码的两端分别调用QueryPerformanceCounter以取得高精度运行计数器的数值n1,n2。两次数  
值的差值通过f换算成时间间隔,t=(n2-n1)/f。  
   
下面举一个例子来演示这种方法的使用及它的精确度。  
   
在VC   6.0   下用MFC建立一个对话框工程,取名为HightTimer.在对话框面板中控件的布局如下图:  
   
   
其中包含两个静态文本框,两个编辑框和两个按纽。上面和下面位置的编辑框的ID分别为IDC_E_TEST和IDC_E_ACT  
UAL,通过MFC   ClassWizard添加的成员变量也分别对应为DWORD   m_dwTest和DWORD   m_dwAct.  
“退出”按纽的ID为IDOK,“开始测试”按纽ID为IDC_B_TEST,用MFC  
ClassWizard添加此按纽的单击消息处理函数如下:  
   
void   CHightTimerDlg::OnBTest()    
{  
//   TODO:   Add   your   control   notification   handler   code   here  
UpdateData(TRUE);   //取输入的测试时间值到与编辑框相关联的成员变量m_dwTest中  
   
LARGE_INTEGER   frequence;//LARGE_INTEGER是一个联合,其中LOWPART为低32位,HIGHPART为高32位,  
//两者构成一个结构,而QuadPart是其中的64位符号整数,为LongLong类型  
if(!QueryPerformanceFrequency(   &frequence))   //取高精度运行计数器的频率,若硬件不支持则返回FALSE  
MessageBox("Your   computer   hardware   doesn't   support   the   high-resolution   performance   counter",  
"Not   Support",   MB_ICONEXCLAMATION   |   MB_OK);    
   
LARGE_INTEGER   test,   ret;  
test.QuadPart   =   frequence.QuadPart   *   m_dwTest   /   1000000;  
//通过频率换算微秒数到对应的数量(与CPU时钟有关),1秒=1000000微秒  
//test   中存储着m_dwTest毫秒所需的次数  
ret   =   MySleep(   test   );   //调用此函数开始延时,返回实际花销的数量  
   
m_dwAct   =   (DWORD)(1000000   *   ret.QuadPart   /   frequence.QuadPart   );   //换算到微秒数  
   
UpdateData(FALSE);   //显示到对话框面板  
}  
   
其中上面调用的MySleep函数如下:  
   
LARGE_INTEGER   CHightTimerDlg::MySleep(LARGE_INTEGER   Interval)  
///////////////////////////////////////////////////////////////////////////////////////////////////  
//////////  
//   功能:执行实际的延时功能  
//   参数:Interval   参数为需要执行的延时与时间有关的数量  
//   返回值:返回此函数执行后实际所用的时间有关的数量  
///////////////////////////////////////////////////////////////////////////////////////////////////  
////////  
{  
LARGE_INTEGER   privious,   current,   Elapse;  
   
QueryPerformanceCounter(   &privious   );  
current   =   privious;  
   
while(   current.QuadPart   -   privious.QuadPart   <   Interval.QuadPart   )  
QueryPerformanceCounter(   ¤t   );  
   
Elapse.QuadPart   =   current.QuadPart   -   privious.QuadPart;  
   
return   Elapse;  
}  
注:别忘了在头文件中为此函数添加函数声明。  
   
至此,可以编译和执行此工程了,当测试时间超过3微秒时,准确度已经非常高了,此时机器执行本身延时函数代码的时间对需要延时的时间影响很小了。  
   
上面的函数由于演示测试的需要,没有在函数级封装,下面给出的函数基本上可以以全局函数的形式照搬到别的  
程序中。  
   
BOOL   MySleep(DWORD   dwInterval)  
///////////////////////////////////////////////////////////////////////////////////////////////////  
//////////  
//   功能:执行微秒级的延时功能  
//   参数:Interval   参数为需要的延时数(单位:微秒)  
//   返回值:若计算机硬件不支持此功能,返回FALSE,若函数执行成功,返回TRUE  
///////////////////////////////////////////////////////////////////////////////////////////////////  
////////  
{  
BOOL   bNormal   =   TRUE;  
LARGE_INTEGER   frequence,   privious,   current,   interval;  
   
if(!QueryPerformanceFrequency(   &frequence))  
{  
::MessageBox(NULL,   "Your   computer   hardware   doesn't   support   the   high-resolution   performance  
counter",  
"Not   Support",   MB_ICONEXCLAMATION   |   MB_OK);   //或其它的提示信息  
return   FALSE;  
}  
   
interval.QuadPart   =   frequence.QuadPart   *   dwInterval   /   1000000;  
   
bNormal   =   bNormal   &&   QueryPerformanceCounter(   &privious   );  
current   =   privious;  
   
while(   current.QuadPart   -   privious.QuadPart   <   interval.QuadPart   )  
bNormal   =   bNormal   &&   QueryPerformanceCounter(   ¤t   );  
   
return   bNormal;  
}  
   
需要指出的是,由于在此函数中的代码很多,机器在执行这些代码所花费的时间也很长,所以在需要几个微秒的  
延时时,会影响精度。实际上,读者在熟悉这种方法后,只要使用QueryPerformanceFrequency和QueryPerforman  
ceCounter这两个函数就能按实际需要写出自己的延时代码了。  
   
   
   
给你个类吧,我在用呢  
   
//   Elapsed.h:   interface   for   the   CElapsed   class.  
//  
//////////////////////////////////////////////////////////////////////  
   
#if   !defined(AFX_ELAPSED_H__4A992E21_8B47_11D6_B1B2_FFFCE130B010__INCLUDED_)  
#define   AFX_ELAPSED_H__4A992E21_8B47_11D6_B1B2_FFFCE130B010__INCLUDED_  
   
#if   _MSC_VER   >   1000  
#pragma   once  
#endif   //   _MSC_VER   >   1000  
   
class   CElapsed      
{  
private:  
   int Initialized;  
   __int64 Frequency;  
   __int64 BeginTime;  
   
public:  
   BOOL   Avaliable();  
   double   End();  
   BOOL   Begin();  
   CElapsed();  
   virtual   ~CElapsed();    
};  
   
#endif   //   !defined(AFX_ELAPSED_H__4A992E21_8B47_11D6_B1B2_FFFCE130B010__INCLUDED_)  
   
   
   
//   Elapsed.cpp:   implementation   of   the   CElapsed   class.  
//  
//////////////////////////////////////////////////////////////////////  
   
#include   "stdafx.h"  
//#include   "myimage.h"  
#include   "Elapsed.h"  
   
#ifdef   _DEBUG  
#undef   THIS_FILE  
static   char   THIS_FILE[]=__FILE__;  
#define   new   DEBUG_NEW  
#endif  
   
//////////////////////////////////////////////////////////////////////  
//   Construction/Destruction  
//////////////////////////////////////////////////////////////////////  
   
CElapsed::CElapsed()  
{  
   Initialized=QueryPerformanceFrequency((LARGE_INTEGER   *)&Frequency);  
}  
   
CElapsed::~CElapsed()  
{  
   
}  
   
BOOL   CElapsed::Begin()  
{  
   if(!Initialized)  
    return 0;
   return   QueryPerformanceCounter((LARGE_INTEGER   *)&BeginTime);  
}
    
double   CElapsed::End()
{  
   if(!Initialized)  
    return 0;
   __int64   endtime;  
   QueryPerformanceCounter((LARGE_INTEGER   *)&endtime);  
   
   __int64   elapsed=endtime-BeginTime;  
   
   return   (double)elapsed/(double)Frequency;  
}    
BOOL   CElapsed::Avaliable()
{  
   return Initialized;  
}  
    

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

分享: