/******************************************************************** created: 2008/12/30 created: 30:12:2008 14:07 file: ProfileAnalyze.h author: 管传淇 purpose: *********************************************************************/ #ifndef _PROFILE_ANALYZE_H_ #define _PROFILE_ANALYZE_H_ #ifdef WIN32 #include #include #include #include #include #include using namespace std; //CPU的时钟周期 inline unsigned __int64 GetProfileCounter() { DWORD dwLow, dwHigh; _asm{ cpuid ;force all previous instruction to comple rdtsc ;read time stamp counter mov dwLow, eax mov dwHigh,edx } return ((unsigned __int64)dwHigh)<<32|dwLow; } //函数跟踪类,跟踪函数的执行时间,执行次数 struct FuncTracker { FuncTracker():timeTrack(0),startCheckTime(0),m_callCount(0),maxSpendTime(0){} //开始计时 void StartCheck() { m_callCount++;//调用次数增加 startCheckTime = GetProfileCounter(); } //结束计时 void EndCheck() { unsigned __int64 endCheckTime = GetProfileCounter(); endCheckTime -= startCheckTime; //获取最大的 if ( endCheckTime > maxSpendTime ) maxSpendTime = endCheckTime; timeTrack += endCheckTime;//获取本次运行时间 } //获取函数在监测中花费的总时间 unsigned __int64 GetSpendTime() { return timeTrack; } //获取函数在监测中被调用的次数 unsigned GetCallCounter() { return m_callCount; } //获取在监视下,该函数所花费的最大执行时间 unsigned __int64 GetMaxSpendTime() { return maxSpendTime; } //清除函数监测信息 void ClearTracker() { startCheckTime = timeTrack = m_callCount = 0 ;} public: unsigned __int64 startCheckTime;//本次开始计时的时间 unsigned __int64 timeTrack;//在监视下,该函数所花费的总时间 unsigned m_callCount;//被调用的次数 unsigned __int64 maxSpendTime;//该函数所花费的最大的时间 }; extern bool bProfileSwich;//优化开关 class ProfileAnalyze; //性能分析管理类 class ProfileAnalyzeManager { public: void PushProfileAnalyze( string& strFunc, ProfileAnalyze* pProfile ) { mStrToAnalyzeMap[strFunc] = pProfile; } ProfileAnalyze* GetProfileAnalyze( const string& strFunc ) { std::map::iterator lter = mStrToAnalyzeMap.find( strFunc ); if ( lter != mStrToAnalyzeMap.end() ) { return lter->second; } return NULL; } void ClearAllProfileAnalyze() { std::map::iterator lter = mStrToAnalyzeMap.begin(); if ( lter != mStrToAnalyzeMap.end() ) { ProfileAnalyze * pAnalyze = lter->second; } } private: std::map mStrToAnalyzeMap; }; extern ProfileAnalyzeManager sProfileManager; //性能分析类 class ProfileAnalyze { public: ProfileAnalyze( const char* AnalyzeName ):trackCount(0) { mAnalyzeName = AnalyzeName; } FuncTracker * PushNewTracker( const char* func ) { FuncTracker* pTracker = &mFuncTrackerArr[trackCount++]; mFuncTrackerMap.insert( std::pair(func,pTracker) ); return pTracker; } //获取性能分析报告 void GetAnaylzeReport() { if ( !bProfileSwich ) return; unsigned __int64 mTotalTime = 0; for ( unsigned int i = 0 ; i< trackCount; i++ ) { FuncTracker& pTracker = mFuncTrackerArr[i]; mTotalTime += pTracker.GetSpendTime();//本次计时花费的总时间 } char fileBuf[56]={0}; struct tm ptr; time_t lt; lt = time(NULL); gmtime_s(&ptr,<); sprintf_s( fileBuf ,"Profile\\%d_%d_%d_%d_%d_%d_%s_AnalyzeReport.txt", 1900 + ptr.tm_year, ptr.tm_mon+1, ptr.tm_mday, ptr.tm_hour, ptr.tm_min, ptr.tm_sec, mAnalyzeName.c_str() ); ofstream analyzefile; analyzefile.open( fileBuf ); analyzefile<<"性能分析"<::iterator lter = mFuncTrackerMap.begin() ; lter != mFuncTrackerMap.end(); ++lter ) { FuncTracker* pTracker = lter->second; if ( !pTracker ) continue; unsigned __int64 avgSpendTime = 0; unsigned callCount = pTracker->GetCallCounter(); unsigned __int64 spendingTime = pTracker->GetSpendTime(); if ( callCount != 0 ) avgSpendTime = spendingTime/callCount; //花费的时间所占的百分比 double spendpercent = ((double)spendingTime/(double)mTotalTime)*100; //分析的报告数据 analyzefile<< lter->first<<" "<GetMaxSpendTime()<<" "< mFuncTrackerMap; std::string mAnalyzeName;//分析器的标识 }; //函数跟踪的包装 class FuncWrapper { public: FuncWrapper ( FuncTracker* tmpTracker ):mpTimeTracker(tmpTracker) { if ( mpTimeTracker && bProfileSwich ) mpTimeTracker->StartCheck(); } ~FuncWrapper() { if ( mpTimeTracker && bProfileSwich ) mpTimeTracker->EndCheck(); } private: FuncTracker* mpTimeTracker; }; #define PROFILE_MARK( T )\ typedef class Profile##T:public ProfileAnalyze{\ public:\ Profile##T():ProfileAnalyze(#T){\ sProfileManager.PushProfileAnalyze( mAnalyzeName, this );\ }\ }Monitor##T;\ extern Monitor##T T;\ #define PROFILE_MARK_STEP( T , STEP )\ typedef struct Profile##T##STEP{\ Profile##T##STEP(){\ m_pTracker = T.PushNewTracker( #STEP );}\ FuncTracker* GetFuncTracker(){ return m_pTracker; }\ FuncTracker* m_pTracker;\ }Monitor##T##STEP;\ extern Monitor##T##STEP T##STEP;\ #define ANALYZE_MONITOR( T ,STEP )\ FuncWrapper(T##STEP.GetFuncTracker());\ #define ANALYZE_MONITOR_BEGIN( T,STEP )\ if( bProfileSwich ){\ T##STEP.GetFuncTracker()->StartCheck();}\ #define ANALYZE_MONITOR_END( T,STEP )\ if( bProfileSwich ){\ T##STEP.GetFuncTracker()->EndCheck();}\ #define GET_ANALYZE_REPORT( T ){\ ProfileAnalyze* pAnalyze = sProfileManager.GetProfileAnalyze( T );\ if ( pAnalyze ) pAnalyze->GetAnaylzeReport();\ };\ #define PROFILE_INIT ProfileAnalyzeManager sProfileManager;\ bool bProfileSwich = false;\ #define DECLARE_PROFILE_MARK( T )\ Monitor##T T;\ #define DECLARE_PROFILE_MARK_STEP( T,STEP )\ Monitor##T##STEP T##STEP; #define OPEN_PROFILE_SWICH bProfileSwich =true; #define CLOSE_PROFILE_SWICH bProfileSwich = false; #else #define PROFILE_MARK(T) #define PROFILE_MARK_STEP( T , STEP) #define ANALYZE_MONITOR( T,STEP ) #define GET_ANALYZE_REPORT( T ) #define PROFILE_INIT #define DECLARE_PROFILE_MARK(T) #define DECLARE_PROFILE_MARK_STEP(T,STEP) #define OPEN_PROFILE_SWICH #define CLOSE_PROFILE_SWICH #endif//ACE_WIN32 #endif //_PROFILE_ANALYZE_H_