C++高精度實現計算程序運行時間


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM