Jolt Physics
A multi core friendly Game Physics Engine
Loading...
Searching...
No Matches
Profiler.h
Go to the documentation of this file.
1// Jolt Physics Library (https://github.com/jrouwe/JoltPhysics)
2// SPDX-FileCopyrightText: 2021 Jorrit Rouwe
3// SPDX-License-Identifier: MIT
4
5#pragma once
6
8#include <mutex>
10
14
15#if defined(JPH_EXTERNAL_PROFILE)
16
18
23class alignas(16) ExternalProfileMeasurement : public NonCopyable
24{
25public:
27 ExternalProfileMeasurement(const char *inName, uint32 inColor = 0);
28 ~ExternalProfileMeasurement();
29
30private:
31 uint8 mUserData[64];
32};
33
35
37// Macros to do the actual profiling
39
40JPH_SUPPRESS_WARNING_PUSH
41JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
42
43// Dummy implementations
44#define JPH_PROFILE_THREAD_START(name)
45#define JPH_PROFILE_THREAD_END()
46#define JPH_PROFILE_NEXTFRAME()
47#define JPH_PROFILE_DUMP(...)
48
49// Scope profiling measurement
50#define JPH_PROFILE_TAG2(line) profile##line
51#define JPH_PROFILE_TAG(line) JPH_PROFILE_TAG2(line)
52
62#define JPH_PROFILE(...) ExternalProfileMeasurement JPH_PROFILE_TAG(__LINE__)(__VA_ARGS__)
63
64// Scope profiling for function
65#define JPH_PROFILE_FUNCTION() JPH_PROFILE(JPH_FUNCTION_NAME)
66
67JPH_SUPPRESS_WARNING_POP
68
69#elif defined(JPH_PROFILE_ENABLED)
70
72
73class ProfileSample;
74class ProfileThread;
75
77class Profiler : public NonCopyable
78{
79public:
81
83 void NextFrame();
84
87 void Dump(const string_view &inTag = string_view());
88
90 void AddThread(ProfileThread *inThread);
91
93 void RemoveThread(ProfileThread *inThread);
94
97
98private:
100 struct ThreadSamples
101 {
102 String mThreadName;
103 ProfileSample * mSamplesBegin;
104 ProfileSample * mSamplesEnd;
105 };
106
108 class Aggregator
109 {
110 public:
112 Aggregator(const char *inName) : mName(inName) { }
113
115 void AccumulateMeasurement(uint64 inCyclesInCallWithChildren, uint64 inCyclesInChildren)
116 {
117 mCallCounter++;
118 mTotalCyclesInCallWithChildren += inCyclesInCallWithChildren;
119 mTotalCyclesInChildren += inCyclesInChildren;
120 mMinCyclesInCallWithChildren = min(inCyclesInCallWithChildren, mMinCyclesInCallWithChildren);
121 mMaxCyclesInCallWithChildren = max(inCyclesInCallWithChildren, mMaxCyclesInCallWithChildren);
122 }
123
125 bool operator < (const Aggregator &inRHS) const
126 {
127 return mTotalCyclesInCallWithChildren > inRHS.mTotalCyclesInCallWithChildren;
128 }
129
131 const char * mName;
132
134 uint32 mCallCounter = 0;
135 uint64 mTotalCyclesInCallWithChildren = 0;
136 uint64 mTotalCyclesInChildren = 0;
137 uint64 mMinCyclesInCallWithChildren = 0xffffffffffffffffUL;
138 uint64 mMaxCyclesInCallWithChildren = 0;
139 };
140
141 using Threads = Array<ThreadSamples>;
142 using Aggregators = Array<Aggregator>;
143 using KeyToAggregator = UnorderedMap<const char *, size_t>;
144
146 static void sAggregate(int inDepth, uint32 inColor, ProfileSample *&ioSample, const ProfileSample *inEnd, Aggregators &ioAggregators, KeyToAggregator &ioKeyToAggregator);
147
149 void DumpInternal();
150 void DumpList(const char *inTag, const Aggregators &inAggregators);
151 void DumpChart(const char *inTag, const Threads &inThreads, const KeyToAggregator &inKeyToAggregators, const Aggregators &inAggregators);
152
153 std::mutex mLock;
154 Array<ProfileThread *> mThreads;
155 bool mDump = false;
156 String mDumpTag;
157};
158
159// Class that contains the information of a single scoped measurement
160class alignas(16) ProfileSample : public NonCopyable
161{
162public:
164
165 const char * mName;
171};
172
175{
176public:
178
180 inline ProfileThread(const string_view &inThreadName);
181 inline ~ProfileThread();
182
183 static const uint cMaxSamples = 65536;
184
188
189 static thread_local ProfileThread *sInstance;
190};
191
194{
195public:
197 inline ProfileMeasurement(const char *inName, uint32 inColor = 0);
198 inline ~ProfileMeasurement();
199
200private:
201 ProfileSample * mSample;
202 ProfileSample mTemp;
203
204 static bool sOutOfSamplesReported;
205};
206
208
209#include "Profiler.inl"
210
212// Macros to do the actual profiling
214
215JPH_SUPPRESS_WARNING_PUSH
216JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
217
218
219#define JPH_PROFILE_START(name) do { Profiler::sInstance = new Profiler; JPH_PROFILE_THREAD_START(name); } while (false)
220
222#define JPH_PROFILE_END() do { JPH_PROFILE_THREAD_END(); delete Profiler::sInstance; Profiler::sInstance = nullptr; } while (false)
223
225#define JPH_PROFILE_THREAD_START(name) do { if (Profiler::sInstance) ProfileThread::sInstance = new ProfileThread(name); } while (false)
226
228#define JPH_PROFILE_THREAD_END() do { delete ProfileThread::sInstance; ProfileThread::sInstance = nullptr; } while (false)
229
231#define JPH_PROFILE_TAG2(line) profile##line
232#define JPH_PROFILE_TAG(line) JPH_PROFILE_TAG2(line)
233#define JPH_PROFILE(...) ProfileMeasurement JPH_PROFILE_TAG(__LINE__)(__VA_ARGS__)
234
236#define JPH_PROFILE_FUNCTION() JPH_PROFILE(JPH_FUNCTION_NAME)
237
239#define JPH_PROFILE_NEXTFRAME() Profiler::sInstance->NextFrame()
240
242#define JPH_PROFILE_DUMP(...) Profiler::sInstance->Dump(__VA_ARGS__)
243
244JPH_SUPPRESS_WARNING_POP
245
246#else
247
249// Dummy profiling instructions
251
252JPH_SUPPRESS_WARNING_PUSH
253JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
254
255#define JPH_PROFILE_START(name)
256#define JPH_PROFILE_END()
257#define JPH_PROFILE_THREAD_START(name)
258#define JPH_PROFILE_THREAD_END()
259#define JPH_PROFILE(...)
260#define JPH_PROFILE_FUNCTION()
261#define JPH_PROFILE_NEXTFRAME()
262#define JPH_PROFILE_DUMP(...)
263
264JPH_SUPPRESS_WARNING_POP
265
266#endif
#define JPH_SUPPRESS_WARNINGS_STD_BEGIN
Definition: Core.h:245
uint32_t uint32
Definition: Core.h:312
#define JPH_SUPPRESS_WARNINGS_STD_END
Definition: Core.h:255
unsigned int uint
Definition: Core.h:309
#define JPH_NAMESPACE_END
Definition: Core.h:240
#define JPH_CLANG_SUPPRESS_WARNING(w)
Definition: Core.h:133
uint8_t uint8
Definition: Core.h:310
uint64_t uint64
Definition: Core.h:313
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:234
#define JPH_OVERRIDE_NEW_DELETE
Macro to override the new and delete functions.
Definition: Memory.h:29
std::basic_string< char, std::char_traits< char >, STLAllocator< char > > String
Definition: STLAllocator.h:82
std::vector< T, STLAllocator< T > > Array
Definition: STLAllocator.h:81
std::unordered_map< Key, T, Hash, KeyEqual, STLAllocator< pair< const Key, T > > > UnorderedMap
Definition: UnorderedMap.h:13
Class that makes another class non-copyable. Usage: Inherit from NonCopyable.
Definition: NonCopyable.h:11
Create this class on the stack to start sampling timing information of a particular scope.
Definition: Profiler.h:194
~ProfileMeasurement()
Definition: Profiler.inl:57
Definition: Profiler.h:161
uint32 mColor
Color to use for this sample.
Definition: Profiler.h:166
uint8 mUnused[3]
Definition: Profiler.h:168
uint64 mEndCycle
Cycle counter at end of measurement.
Definition: Profiler.h:170
JPH_OVERRIDE_NEW_DELETE const char * mName
User defined name of this item.
Definition: Profiler.h:165
uint8 mDepth
Calculated depth.
Definition: Profiler.h:167
uint64 mStartCycle
Cycle counter at start of measurement.
Definition: Profiler.h:169
Collects all samples of a single thread.
Definition: Profiler.h:175
ProfileSample mSamples[cMaxSamples]
Buffer of samples.
Definition: Profiler.h:186
uint mCurrentSample
Next position to write a sample to.
Definition: Profiler.h:187
~ProfileThread()
Definition: Profiler.inl:17
static thread_local ProfileThread * sInstance
Definition: Profiler.h:189
String mThreadName
Name of the thread that we're collecting information for.
Definition: Profiler.h:185
static const uint cMaxSamples
Definition: Profiler.h:183
Singleton class for managing profiling information.
Definition: Profiler.h:78
void Dump(const string_view &inTag=string_view())
Definition: Profiler.cpp:43
void RemoveThread(ProfileThread *inThread)
Remove a thread from being instrumented.
Definition: Profiler.cpp:56
void AddThread(ProfileThread *inThread)
Add a thread to be instrumented.
Definition: Profiler.cpp:49
static Profiler * sInstance
Singleton instance.
Definition: Profiler.h:96
JPH_OVERRIDE_NEW_DELETE void NextFrame()
Increments the frame counter to provide statistics per frame.
Definition: Profiler.cpp:29