Pyrogenesis HEAD
Pyrogenesis, a RTS Engine
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
36class CProfileManager;
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{
52public:
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 );
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
88private:
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
113class CProfileManager : public Singleton<CProfileManager>
114{
115public:
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
139private:
142
144
146};
147
148#define g_Profiler CProfileManager::GetSingleton()
149
151{
152public:
153 CProfileSample(const char* name);
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
New profiler (complementing the older CProfileManager)
Definition: Profile.h:114
const CProfileNode * GetCurrent()
Definition: Profile.h:136
void Turn()
Definition: Profile.cpp:449
const CProfileNode * GetRoot()
Definition: Profile.h:137
void Start(const char *name)
Definition: Profile.cpp:409
void PerformStructuralReset()
Definition: Profile.cpp:464
void Stop()
Definition: Profile.cpp:423
CProfileNode * root
Definition: Profile.h:140
CProfileManager()
Definition: Profile.cpp:398
~CProfileManager()
Definition: Profile.cpp:404
CProfileNode * current
Definition: Profile.h:141
void Reset()
Definition: Profile.cpp:429
void StructuralReset()
Definition: Profile.cpp:454
void StartScript(const char *name)
Definition: Profile.cpp:416
void Frame()
Definition: Profile.cpp:434
bool needs_structural_reset
Definition: Profile.h:143
Class CProfileNodeTable: Implement ProfileViewer's AbstractProfileTable interface in order to display...
Definition: Profile.cpp:42
Definition: Profile.h:50
std::vector< CProfileNode * >::const_iterator const_profile_iterator
Definition: Profile.h:54
void Reset()
Definition: Profile.cpp:328
CProfileNodeTable * display_table
Definition: Profile.h:110
const char * GetName() const
Definition: Profile.h:59
void Call()
Definition: Profile.cpp:377
RingBuf< double, PROFILE_AMORTIZE_TURNS > time_per_turn
Definition: Profile.h:102
const CProfileNode * GetChild(const char *name) const
Definition: Profile.cpp:279
std::vector< CProfileNode * > script_children
Definition: Profile.h:109
int recursion
Definition: Profile.h:105
double time_frame_current
Definition: Profile.h:99
RingBuf< int, PROFILE_AMORTIZE_TURNS > calls_per_turn
Definition: Profile.h:97
bool CanExpand()
Definition: Profile.cpp:323
double GetTurnTime() const
Definition: Profile.cpp:274
RingBuf< double, PROFILE_AMORTIZE_FRAMES > time_per_frame
Definition: Profile.h:101
double GetTurnCalls() const
Definition: Profile.cpp:269
std::vector< CProfileNode * > children
Definition: Profile.h:108
void Frame()
Definition: Profile.cpp:347
CProfileNode * GetParent() const
Definition: Profile.h:75
NONCOPYABLE(CProfileNode)
const std::vector< CProfileNode * > * GetScriptChildren() const
Definition: Profile.h:69
RingBuf< int, PROFILE_AMORTIZE_FRAMES > calls_per_frame
Definition: Profile.h:96
bool Return()
Definition: Profile.cpp:387
const char * name
Definition: Profile.h:92
double start
Definition: Profile.h:104
double GetFrameTime() const
Definition: Profile.cpp:264
double GetFrameCalls() const
Definition: Profile.cpp:259
CProfileNode(const char *name, CProfileNode *parent)
Definition: Profile.cpp:228
CProfileNode * parent
Definition: Profile.h:107
const CProfileNode * GetScriptChild(const char *name) const
Definition: Profile.cpp:289
const std::vector< CProfileNode * > * GetChildren() const
Definition: Profile.h:68
int calls_turn_current
Definition: Profile.h:95
std::vector< CProfileNode * >::iterator profile_iterator
Definition: Profile.h:53
int calls_frame_current
Definition: Profile.h:94
double time_turn_current
Definition: Profile.h:100
~CProfileNode()
Definition: Profile.cpp:240
void Turn()
Definition: Profile.cpp:362
Definition: Profile.h:151
~CProfileSample()
Definition: Profile.cpp:483
CProfileSample(const char *name)
Definition: Profile.cpp:473
Template base class for singletons.
Definition: Singleton.h:34