⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 iceprofiler.h

📁 使用stl技术,(还没看,是听说的)
💻 H
字号:
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/**
 *	Contains profiling code.
 *	\file		IceProfiler.h
 *	\author		Pierre Terdiman
 *	\date		April, 4, 2000
 */
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Include Guard
#ifndef __ICEPROFILER_H__
#define __ICEPROFILER_H__

	// Forward declarations
	class Profiler;

	FUNCTION ICECORE_API void		SetBaseTime(udword time);
	FUNCTION ICECORE_API udword		GetBaseTime();
	FUNCTION ICECORE_API Profiler&	GetProfiler();

	#define PROFILE_APP		// It's been tested with various scenes that profiling the app doesn't slow it down at all

#ifdef PROFILE_APP
	#define PROFILE_START(label)	GetProfiler().StartProfile(label);
	#define PROFILE_END(label)		GetProfiler().EndProfile(label);
#else
	#define PROFILE_START(label)
	#define PROFILE_END(label)
#endif

	//! This function initializes the profiler by counting the cpuid overhead.
	//! This is done 3 times on purpose, since cpuid takes a longer time to execute the first times it's called.
	//! "cpuid" is used before rdtsc to prevent out-of-sequence execution from producing wrong results.
	//! For more details, read Intel's application notes "Using the RDTSC instruction for performance monitoring".
	//!	\see		StartProfile
	//!	\see		EndProfile
	inline_ void InitProfiler()
	{
		udword cyc, Base;
		_asm{
			cpuid
			rdtsc
			mov		cyc, eax
			cpuid
			rdtsc
			sub		eax, cyc
			mov		Base, eax

			cpuid
			rdtsc
			mov		cyc, eax
			cpuid
			rdtsc
			sub		eax, cyc
			mov		Base, eax

			cpuid
			rdtsc
			mov		cyc, eax
			cpuid
			rdtsc
			sub		eax, cyc
			mov		Base, eax
		}
		SetBaseTime(Base);
	}

	//!	This function starts recording the number of cycles elapsed.
	//!	\param		val		[out] address of a 32 bits value where the system should store the result.
	//!	\see		EndProfile
	//!	\see		InitProfiler
	inline_ void	StartProfile(udword& val)
	{
		__asm{
			cpuid
			rdtsc
			mov		ebx, val
			mov		[ebx], eax
		}
	}

	//!	This function ends recording the number of cycles elapsed.
	//!	\param		val		[out] address to store the number of cycles elapsed since the last StartProfile.
	//!	\see		StartProfile
	//!	\see		InitProfiler
	inline_ void	EndProfile(udword& val)
	{
		__asm{
			cpuid
			rdtsc
			mov		ebx, val
			sub		eax, [ebx]
			mov		[ebx], eax
		}
		val-=GetBaseTime();
	}

	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/**
	 *	User-callback, called by the profiler on starting/ending profiling a given process.
	 *	\param		bool		[in] true when profile starts, false when profile ends
	 *	\param		user_data	[in] user-defined data
	 */
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	typedef void	(*PROFILE_CALLBACK)	(bool begin, udword user_data);

	struct ICECORE_API ProfileData
	{
		udword		Order;				//!< Insertion order
		char*		Label;				//!< User-defined label
		udword		NbCycles;			//!< Number of elapsed cycles
		float		Percents;			//!< NbCycles * 100 / TotalNbCycles
		udword		RecursionLevel;		//!< Level of recursion
	};

	class ICECORE_API Profiler
	{
		public:
		// Constructor/Destructor
									Profiler();
									~Profiler();
		// Start of frame call
				void				Reset();
		// Profiling
		inline_	bool				StartProfile(const char* label=null)
									{
										// Check the user has called Reset() beforehand.
										if(!mIsReady)	return false;
										return _StartProfile(label);
									}

		inline_	bool				EndProfile(const char* label=null)
									{
										// Check the user has called Reset() beforehand.
										if(!mIsReady)	return false;
										return _EndProfile(label);
									}

		// End of frame call
				ProfileData*		GetResults(udword& nbrecords, udword& totalnbcycles);

		// Callback control - used to pick out one particular event
		inline_	void				SetUserData(udword data)				{ mUserData	= data;		}
		inline_	void				SetCallback(PROFILE_CALLBACK callback)	{ mCallback	= callback;	}
		inline_	void				SetCallbackEvent(const char* label)		{ mEvent	= label;	}

		private:
		// User callback
				udword				mUserData;			//!< User-defined data sent to the possible callback
				PROFILE_CALLBACK	mCallback;			//!< User-defined callback
				const char*			mEvent;				//!< Event triggering off the callback

				LIFOStack			mCyclesCounters;	//!< Elapsed cycles
				LIFOStack			mOrder;				//!< Insertion orders
				Container			mRecorder;			//!< Data records
				udword				mNbRecords;			//!< Current number of recorded events
				udword				mRecursionLevel;	//!< Current recursion level
				bool				mIsReady;			//!< true if Reset() has been called
				bool				mEndingPending;		//!< true if the ending callback is pending
		// Internal methods
				bool				_StartProfile(const char* label);
				bool				_EndProfile(const char* label);
	};

#endif // __ICEPROFILER_H__

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -