Pyrogenesis  trunk
Profile.h
Go to the documentation of this file.
1 /* Copyright (C) 2022 Wildfire Games.
2  * This file is part of 0 A.D.
3  *
4  * 0 A.D. is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * 0 A.D. is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>.
16  */
17 
18 /*
19  * GPG3-style hierarchical profiler
20  */
21 
22 #ifndef INCLUDED_PROFILE
23 #define INCLUDED_PROFILE
24 
25 #include <vector>
26 
27 #include "lib/adts/ring_buf.h"
29 #include "ps/Profiler2.h"
30 #include "ps/Singleton.h"
31 
32 
33 #define PROFILE_AMORTIZE_FRAMES 30
34 #define PROFILE_AMORTIZE_TURNS 5
35 
36 class CProfileManager;
37 class CProfileNodeTable;
38 
39 // To profile scripts usefully, we use a call hook that's called on every enter/exit,
40 // and need to find the function name. But most functions are anonymous so we make do
41 // with filename plus line number instead.
42 // Computing the names is fairly expensive, and we need to return an interned char*
43 // for the profiler to hold a copy of, so we use boost::flyweight to construct interned
44 // strings per call location.
45 //
46 // TODO: Check again how much the overhead for getting filename and line really is and if
47 // it has increased with the new approach after the SpiderMonkey 31 upgrade.
48 
50 {
52 public:
53  typedef std::vector<CProfileNode*>::iterator profile_iterator;
54  typedef std::vector<CProfileNode*>::const_iterator const_profile_iterator;
55 
56  CProfileNode( const char* name, CProfileNode* parent );
57  ~CProfileNode();
58 
59  const char* GetName() const { return name; }
60 
61  double GetFrameCalls() const;
62  double GetFrameTime() const;
63  double GetTurnCalls() const;
64  double GetTurnTime() const;
65 
66  const CProfileNode* GetChild( const char* name ) const;
67  const CProfileNode* GetScriptChild( const char* name ) const;
68  const std::vector<CProfileNode*>* GetChildren() const { return( &children ); }
69  const std::vector<CProfileNode*>* GetScriptChildren() const { return( &script_children ); }
70 
71  bool CanExpand();
72 
73  CProfileNode* GetChild( const char* name );
74  CProfileNode* GetScriptChild( const char* name );
75  CProfileNode* GetParent() const { return( parent ); }
76 
77  // Resets timing information for this node and all its children
78  void Reset();
79  // Resets frame timings for this node and all its children
80  void Frame();
81  // Resets turn timings for this node and all its children
82  void Turn();
83  // Enters the node
84  void Call();
85  // Leaves the node. Returns true if the node has actually been left
86  bool Return();
87 
88 private:
89  friend class CProfileManager;
90  friend class CProfileNodeTable;
91 
92  const char* name;
93 
98 
103 
104  double start;
106 
108  std::vector<CProfileNode*> children;
109  std::vector<CProfileNode*> script_children;
111 };
112 
113 class CProfileManager : public Singleton<CProfileManager>
114 {
115 public:
116  CProfileManager();
117  ~CProfileManager();
118 
119  // Begins timing for a named subsection
120  void Start( const char* name );
121  void StartScript( const char* name );
122 
123  // Ends timing for the current subsection
124  void Stop();
125 
126  // Resets all timing information
127  void Reset();
128  // Resets frame timing information
129  void Frame();
130  // Resets turn timing information
131  // (Must not be called before Frame)
132  void Turn();
133  // Resets absolutely everything, at the end of this frame
134  void StructuralReset();
135 
136  inline const CProfileNode* GetCurrent() { return( current ); }
137  inline const CProfileNode* GetRoot() { return( root ); }
138 
139 private:
142 
144 
145  void PerformStructuralReset();
146 };
147 
148 #define g_Profiler CProfileManager::GetSingleton()
149 
151 {
152 public:
153  CProfileSample(const char* name);
154  ~CProfileSample();
155 };
156 
157 // Put a PROFILE("xyz") block at the start of all code to be profiled.
158 // Profile blocks last until the end of the containing scope.
159 #define PROFILE(name) CProfileSample __profile(name)
160 // Cheat a bit to make things slightly easier on the user
161 #define PROFILE_START(name) { CProfileSample __profile(name)
162 #define PROFILE_END(name) }
163 
164 // Do both old and new profilers simultaneously (1+2=3), for convenience.
165 #define PROFILE3(name) PROFILE(name); PROFILE2(name)
166 
167 // Also do GPU
168 #define PROFILE3_GPU(name) PROFILE(name); PROFILE2(name); PROFILE2_GPU(name)
169 
170 #endif // INCLUDED_PROFILE
double GetFrameCalls() const
Definition: Profile.cpp:259
RingBuf< double, PROFILE_AMORTIZE_TURNS > time_per_turn
Definition: Profile.h:102
RingBuf< int, PROFILE_AMORTIZE_TURNS > calls_per_turn
Definition: Profile.h:97
void Turn()
Definition: Profile.cpp:362
bool Return()
Definition: Profile.cpp:387
const std::vector< CProfileNode * > * GetScriptChildren() const
Definition: Profile.h:69
const CProfileNode * GetCurrent()
Definition: Profile.h:136
RingBuf< int, PROFILE_AMORTIZE_FRAMES > calls_per_frame
Definition: Profile.h:96
const CProfileNode * GetScriptChild(const char *name) const
Definition: Profile.cpp:289
CProfileNode * parent
Definition: Profile.h:107
CProfileNode * GetParent() const
Definition: Profile.h:75
std::vector< CProfileNode * > children
Definition: Profile.h:108
const CProfileNode * GetRoot()
Definition: Profile.h:137
double time_turn_current
Definition: Profile.h:100
double start
Definition: Profile.h:104
int calls_turn_current
Definition: Profile.h:95
Class CProfileNodeTable: Implement ProfileViewer&#39;s AbstractProfileTable interface in order to display...
Definition: Profile.cpp:41
void Frame()
Definition: Profile.cpp:347
~CProfileNode()
Definition: Profile.cpp:240
NONCOPYABLE(CProfileNode)
CProfileNodeTable * display_table
Definition: Profile.h:110
CProfileNode * root
Definition: Profile.h:140
Definition: Profile.h:150
double GetFrameTime() const
Definition: Profile.cpp:264
int recursion
Definition: Profile.h:105
std::vector< CProfileNode * >::const_iterator const_profile_iterator
Definition: Profile.h:54
bool needs_structural_reset
Definition: Profile.h:143
New profiler (complementing the older CProfileManager)
CProfileNode * current
Definition: Profile.h:141
Definition: Profile.h:113
Definition: Profile.h:49
double GetTurnTime() const
Definition: Profile.cpp:274
void Call()
Definition: Profile.cpp:377
const char * GetName() const
Definition: Profile.h:59
double time_frame_current
Definition: Profile.h:99
friend class CProfileManager
Definition: Profile.h:89
RingBuf< double, PROFILE_AMORTIZE_FRAMES > time_per_frame
Definition: Profile.h:101
CProfileNode(const char *name, CProfileNode *parent)
Definition: Profile.cpp:228
void Reset()
Definition: Profile.cpp:328
int calls_frame_current
Definition: Profile.h:94
Template base class for singletons.
Definition: Singleton.h:33
const char * name
Definition: Profile.h:92
double GetTurnCalls() const
Definition: Profile.cpp:269
std::vector< CProfileNode * > script_children
Definition: Profile.h:109
bool CanExpand()
Definition: Profile.cpp:323
const std::vector< CProfileNode * > * GetChildren() const
Definition: Profile.h:68
std::vector< CProfileNode * >::iterator profile_iterator
Definition: Profile.h:53
const CProfileNode * GetChild(const char *name) const
Definition: Profile.cpp:279