博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C++高精度实现计算程序运行时间
阅读量:5899 次
发布时间:2019-06-19

本文共 5210 字,大约阅读时间需要 17 分钟。

//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;  
}  
    

转载地址:http://eqhsx.baihongyu.com/

你可能感兴趣的文章
IOS Xib使用——为控制器添加Xib文件
查看>>
CentOS 7.0默认使用的是firewall作为防火墙,这里改为iptables防火墙步骤
查看>>
react 取消 eslint
查看>>
【11】ajax请求后台接口数据与返回值处理js写法
查看>>
Python菜鸟之路:Jquery Ajax的使用
查看>>
LeetCode算法题-Maximum Depth of Binary Tree
查看>>
sha1withRSA算法
查看>>
Vim和操作系统剪贴板交互
查看>>
Cox 教学视频5
查看>>
JVM类加载(4)—加载器
查看>>
public/private/protected的具体区别
查看>>
面试宝典——求一个字符串中连续出现次数最多的子串
查看>>
VMware Workstation虚拟机上网设置
查看>>
Jenkins持续集成学习-搭建jenkins问题汇总
查看>>
C#Note13:如何在C#中调用python
查看>>
Android介绍以及源码编译---Android源码下载
查看>>
SpringBoot集成redis缓存
查看>>
sql经典语句
查看>>
使用ffmpeg实现对h264视频解码 -- (实现了一个易于使用的c++封装库)
查看>>
第4周作业-面向对象设计与继承
查看>>