惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

MyScale Blog
MyScale Blog
A
About on SuperTechFans
G
Google Developers Blog
B
Blog RSS Feed
F
Fortinet All Blogs
WordPress大学
WordPress大学
Recent Announcements
Recent Announcements
Hugging Face - Blog
Hugging Face - Blog
Y
Y Combinator Blog
MongoDB | Blog
MongoDB | Blog
小众软件
小众软件
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
T
The Blog of Author Tim Ferriss
Jina AI
Jina AI
IT之家
IT之家
P
Proofpoint News Feed
美团技术团队
量子位
Microsoft Azure Blog
Microsoft Azure Blog
Engineering at Meta
Engineering at Meta
B
Blog
有赞技术团队
有赞技术团队
U
Unit 42

博客园 - JohnsonFeng

JavaScript 性能优化 --By Google V8 Team Manager 在C++中嵌入JavaScript——Google V8 JavaScript Engine使用体验 介绍相似图片搜索:TinEye VC环境OpenSSL编译笔记 Nginx Server 加密库相关资源 C++中使用Expat解析XML 在C++应用中通过Luabind使用lua脚本(一) - JohnsonFeng - 博客园 在动作捕捉系统中使用加速度和倾角传感器 游戏需求分析 慎用CMFCToolBar::CreateEx [Foward]Reduce Exe File Size IOCP在网络应用中常见错误分析 Direct3D程序调试利器 PIX Win 简介 数据自解压简单原理 编写和调试Shader程序(1) 生成均匀“随机数”,一种生成均匀分布数字的简单方法 Visual C++ Profile的简单使用方法 [转]About SIGGRAPH
C++简单的函数计时方法
JohnsonFeng · 2008-07-17 · via 博客园 - JohnsonFeng

   这里提供一个简单的函数计时方法,利用QueryPerformanceFrequency和QueryPerformanceCount函数进行精确计时,这是最精确的计时方法。
   原理是在函数被调用时记录时间,结束时利用局部对象的析构函数再记录一次时间,将这个时间差累积到对应的函数的统计数据中。当程序退出时,全局对象释放,将所有函数的数据输出到调试窗口。使用时,需要再函数开头位置插入一条宏:_PF。需要计时的函数内都插入一条这样的宏。为了方便,宏被定义的比较短。

  FunctionName   ActiveTime    Average  Clled
         WinMain     
5.480105    5.480105     1
    
         MsgProc     
0.975687    0.015245    64
    
         InitD3D     
0.222094    0.222094     1
    
    InitGeometry     
0.004631    0.004631     1
    
          Render     
4.876714    0.021771   224
    
   SetupMatrices     
0.001405    0.000006   224
    
         Cleanup     
0.209167    0.209167     1 

#define PERFDATA_INIT_SIZE 32
#define PERFDATA_INC_SIZE  32
class PerformanceDaemon 
{
private
:
    typedef 
struct
 _PERF_DATA
    
{
        DWORD  nID;
        LPSTR pstrName;
        DWORD TotolCalled;
        LONGLONG TotolTime;
        
//LARGE_INTEGER FuncBeginTime;


    }
PERF_DATA,*LPPERF_DATA;


    LPPERF_DATA m_pDatas;
    DWORD m_dwUsed;
    DWORD m_dwSize;

    LARGE_INTEGER m_TickNow;
    LARGE_INTEGER m_Freq;
    
void
 SetSize(DWORD dwSize)
    
{
        assert(dwSize
>
m_dwUsed);
        LPPERF_DATA pData
=new
 PERF_DATA[dwSize];
        memcpy(pData,m_pDatas,m_dwUsed
*sizeof
(PERF_DATA));
        memset(pData
+m_dwUsed,0,(dwSize-m_dwUsed)*sizeof
(PERF_DATA));
        delete []m_pDatas;
        m_pDatas
=
pData;
        m_dwSize
=
dwSize;
    }

public:

    PerformanceDaemon ()
    
{
        m_pDatas
=0
;
        m_dwUsed
=0
;
        m_dwSize
=0
;
        
        SetSize(PERFDATA_INIT_SIZE);

        QueryPerformanceFrequency(
&
m_Freq); 
        QueryPerformanceCounter(
&
m_TickNow);

    }




    
void FuncStart(LPSTR pstrName,DWORD &nID)
    
{
        
if(nID>=m_dwUsed && nID!=0xFFFFreturn
;
        
if(nID==0xFFFF)    //add new function record;

        {
        

            PERF_DATA data;
            SIZE_T nLenght;
            nLenght
=
strlen(pstrName);
            memset(
&data,0,sizeof
(data));
            data.pstrName
=new CHAR[nLenght+1
];
            strcpy(data.pstrName,pstrName);

            
if(m_dwUsed >=
 m_dwSize) 
                SetSize(m_dwSize
+
PERFDATA_INC_SIZE);
            
            nID
=m_dwUsed++
;
            
            

            m_pDatas[nID]
=
data;

        }

        QueryPerformanceCounter(
&m_TickNow);
    }

    
void GetTime(LONGLONG *pTime)
    
{
        
*pTime=
m_TickNow.QuadPart;
    }


    
void FuncEnd(DWORD nID,LONGLONG *pTime)
    
{
        LARGE_INTEGER TickNow;
        QueryPerformanceCounter(
&
TickNow);
    
        
if(nID>=m_dwUsed && nID!=0xFFFFreturn
;
        m_pDatas[nID].TotolTime
+= TickNow.QuadPart-*
pTime;
        m_pDatas[nID].TotolCalled
++
;
        m_TickNow
=
TickNow;    
    
    }


    
void DumpFunctionPerfmance()
    
{
        CHAR strBuffer[
256
];

        OutputDebugString(
"FunctionName\t\tActiveTime\tAverage\t  Clled\n"
); 
        
for(DWORD i=0;i<m_dwUsed;i++
)
        
{
            
double
 t;
            DWORD n
=
m_pDatas[i].TotolCalled;

            t
=m_pDatas[i].TotolTime/double
(m_Freq.QuadPart); 
            sprintf(strBuffer,
"%16s %12f\t%8f%6u\t\n",m_pDatas[i].pstrName,t,t/
n,n);
            OutputDebugString(strBuffer);
        }

    
    }



    
~PerformanceDaemon ()
    
{
        DumpFunctionPerfmance();
        
for(DWORD i=0;i<m_dwUsed;i++
)
        
{
            delete []m_pDatas[i].pstrName;
        
        }

        

        delete []m_pDatas;
    
    
    }


}
;
PerformanceDaemon  Perf;
class
 PerformanceWatcher
{
    DWORD dwID;    
    LONGLONG StartTime;        
//为了解决嵌套调用问题


public:
    
//just for convinience 

    PerformanceWatcher(LPSTR pstrFunName,DWORD &nID)
    
{
        Perf.FuncStart(pstrFunName,nID);
        dwID
=
nID;
        Perf.GetTime(
&
StartTime);
        
    }

    
~PerformanceWatcher()
    
{
        Perf.FuncEnd(dwID,
&
StartTime);
    }


}
;

#ifdef _DEBUG
#define _PF  \

    
static DWORD __PerfCounter=0xFFFF;\
    PerformanceWatcher __PerfWatcher(__FUNCTION__,__PerfCounter);
#else

#define _PF
#endif 

VOID Cleanup()

{
    _PF
    
if( g_pTexture !=
 NULL )
        g_pTexture
->
Release();

    
if( g_pVB !=
 NULL )
        g_pVB
->
Release();

    
if( g_pd3dDevice !=
 NULL )
        g_pd3dDevice
->
Release();

    
if( g_pD3D !=
 NULL )
        g_pD3D
->
Release();
}

// File: callcaphooks.c

#include 
<stdio.h>
int main();

void _CAP_Enter_Function(void *p) 
{
    
if (p != main) 
        printf(
"Enter function   (at address %p) at %d\n"
            p, GetTickCount());
        
return;
}

void _CAP_Exit_Function(void *p) 
{
    
if (p != main) 
        printf(
"Leaving function (at address %p) at %d\n"
            p, GetTickCount());
    
return;
}