profiler.h

Engine/source/platform/profiler.h

More...

Public Defines

define
define
define

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