profiler.h
Engine/source/platform/profiler.h
Public Defines
Detailed Description
Public Defines
PROFILE_END()
PROFILE_END_NAMED(x)
PROFILE_SCOPE(x)
PROFILE_START(x)
1 2//----------------------------------------------------------------------------- 3// Copyright (c) 2012 GarageGames, LLC 4// 5// Permission is hereby granted, free of charge, to any person obtaining a copy 6// of this software and associated documentation files (the "Software"), to 7// deal in the Software without restriction, including without limitation the 8// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or 9// sell copies of the Software, and to permit persons to whom the Software is 10// furnished to do so, subject to the following conditions: 11// 12// The above copyright notice and this permission notice shall be included in 13// all copies or substantial portions of the Software. 14// 15// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 20// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS 21// IN THE SOFTWARE. 22//----------------------------------------------------------------------------- 23 24#ifndef _PROFILER_H_ 25#define _PROFILER_H_ 26 27#ifndef _TORQUECONFIG_H_ 28#include "torqueConfig.h" 29#endif 30 31#ifdef TORQUE_ENABLE_PROFILER 32 33struct ProfilerData; 34struct ProfilerRootData; 35/// The Profiler is used to see how long a specific chunk of code takes to execute. 36/// All values outputted by the profiler are percentages of the time that it takes 37/// to run entire main loop. 38/// 39/// First, you must #define TORQUE_ENABLE_PROFILER in profiler.h in order to 40/// active it. Examples of script use: 41/// @code 42/// //enables or disables profiling. Data is only gathered when the profiler is enabled. 43/// profilerEnable(bool enable); 44/// profilerReset(); //resets the data gathered by the profiler 45/// profilerDump(); //dumps all profiler data to the console 46/// profilerDumpToFile(string filename); //dumps all profiler data to a given file 47/// profilerMarkerEnable((string markerName, bool enable); //enables or disables a given profile tag 48/// @endcode 49/// 50/// The C++ code side of the profiler uses pairs of PROFILE_START() and PROFILE_END(). 51/// 52/// When using these macros, make sure there is a PROFILE_END() for every PROFILE_START 53/// and a PROFILE_START() for every PROFILE_END(). It is fine to nest these macros, however, 54/// you must make sure that no matter what execution path the code takes, the PROFILE macros 55/// will be balanced. 56/// 57/// The profiler can be used to locate areas of code that are slow or should be considered for 58/// optimization. Since it tracks the relative time of execution of that code to the execution 59/// of the main loop, it is possible to benchmark any given code to see if changes made will 60/// actually improve performance. 61/// 62/// Here are some examples: 63/// @code 64/// PROFILE_START(TerrainRender); 65/// //some code here 66/// PROFILE_START(TerrainRenderGridSquare); 67/// //some code here 68/// PROFILE_END(); 69/// //possibly some code here 70/// PROFILE_END(); 71/// @endcode 72class Profiler 73{ 74 enum { 75 MaxStackDepth = 256, 76 DumpFileNameLength = 256 77 }; 78 U32 mCurrentHash; 79 80 ProfilerData *mCurrentProfilerData; 81 ProfilerData *mProfileList; 82 ProfilerData *mRootProfilerData; 83 84 bool mEnabled; 85 S32 mStackDepth; 86 bool mNextEnable; 87 U32 mMaxStackDepth; 88 bool mDumpToConsole; 89 bool mDumpToFile; 90 char mDumpFileName[DumpFileNameLength]; 91 void dump(); 92 void validate(); 93public: 94 Profiler(); 95 ~Profiler(); 96 97 /// Reset the data in the profiler 98 void reset(); 99 /// Dumps the profile to console 100 void dumpToConsole(); 101 /// Dumps the profile data to a file 102 /// @param fileName filename to dump data to 103 void dumpToFile(const char *fileName); 104 /// Enable profiling 105 void enable(bool enabled); 106 bool isEnabled() { return mNextEnable; } 107 /// Helper function for macro definition PROFILE_START 108 void hashPush(ProfilerRootData *data); 109 /// Helper function for macro definition PROFILE_END 110 void hashPop(ProfilerRootData *expected=<a href="/coding/file/types_8lint_8h/#types_8lint_8h_1a070d2ce7b6bb7e5c05602aa8c308d0c4">NULL</a>); 111 /// Enable a profiler marker 112 void enableMarker(const char *marker, bool enabled); 113#ifdef TORQUE_ENABLE_PROFILE_PATH 114 /// Get current profile path 115 const char * getProfilePath(); 116 /// Construct profile path of given profiler data 117 const char * constructProfilePath(ProfilerData * pd); 118#endif 119}; 120 121extern Profiler *gProfiler; 122 123struct ProfilerRootData 124{ 125 const char *mName; 126 U32 mNameHash; 127 ProfilerData *mFirstProfilerData; 128 ProfilerRootData *mNextRoot; 129 F64 mTotalTime; 130 F64 mSubTime; 131 U32 mTotalInvokeCount; 132 bool mEnabled; 133 134 static ProfilerRootData *sRootList; 135 136 ProfilerRootData(const char *name); 137}; 138 139struct ProfilerData 140{ 141 ProfilerRootData *mRoot; ///< link to root node. 142 ProfilerData *mNextForRoot; ///< links together all ProfilerData's for a particular root 143 ProfilerData *mNextProfilerData; ///< links all the profilerDatas 144 ProfilerData *mNextHash; 145 ProfilerData *mParent; 146 ProfilerData *mNextSibling; 147 ProfilerData *mFirstChild; 148 enum { 149 HashTableSize = 32, 150 }; 151 ProfilerData *mChildHash[HashTableSize]; 152 ProfilerData *mLastSeenProfiler; 153 154 U32 mHash; 155 U32 mSubDepth; 156 U32 mInvokeCount; 157 U64 mStartTime; 158 F64 mTotalTime; 159 F64 mSubTime; 160#ifdef TORQUE_ENABLE_PROFILE_PATH 161 const char * mPath; 162#endif 163}; 164 165 166#define PROFILE_START(name) \ 167static ProfilerRootData pdata##name##obj (#name); \ 168if(gProfiler) gProfiler->hashPush(& pdata##name##obj ) 169 170#define PROFILE_END() if(gProfiler) gProfiler->hashPop() 171 172#define PROFILE_END_NAMED(name) if(gProfiler) gProfiler->hashPop(& pdata##name##obj) 173 174class ScopedProfiler { 175public: 176 ScopedProfiler(ProfilerRootData *data) { 177 if (gProfiler) gProfiler->hashPush(data); 178 } 179 ~ScopedProfiler() { 180 if (gProfiler) gProfiler->hashPop(); 181 } 182}; 183 184#define PROFILE_SCOPE(name) \ 185 static ProfilerRootData pdata##name##obj (#name); \ 186 ScopedProfiler scopedProfiler##name##obj(&pdata##name##obj); 187 188#else 189#define PROFILE_START(x) 190#define PROFILE_END() 191#define PROFILE_SCOPE(x) 192#define PROFILE_END_NAMED(x) 193#endif 194 195#endif 196