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>
9#include <chrono>
11
15
16#if defined(JPH_EXTERNAL_PROFILE)
17
19
24class alignas(16) ExternalProfileMeasurement : public NonCopyable
25{
26public:
28 ExternalProfileMeasurement(const char *inName, uint32 inColor = 0);
29 ~ExternalProfileMeasurement();
30
31private:
32 uint8 mUserData[64];
33};
34
36
38// Macros to do the actual profiling
40
41JPH_SUPPRESS_WARNING_PUSH
42JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
43
44// Dummy implementations
45#define JPH_PROFILE_THREAD_START(name)
46#define JPH_PROFILE_THREAD_END()
47#define JPH_PROFILE_NEXTFRAME()
48#define JPH_PROFILE_DUMP(...)
49
50// Scope profiling measurement
51#define JPH_PROFILE_TAG2(line) profile##line
52#define JPH_PROFILE_TAG(line) JPH_PROFILE_TAG2(line)
53
63#define JPH_PROFILE(...) ExternalProfileMeasurement JPH_PROFILE_TAG(__LINE__)(__VA_ARGS__)
64
65// Scope profiling for function
66#define JPH_PROFILE_FUNCTION() JPH_PROFILE(JPH_FUNCTION_NAME)
67
68JPH_SUPPRESS_WARNING_POP
69
70#elif defined(JPH_PROFILE_ENABLED)
71
73
74class ProfileSample;
75class ProfileThread;
76
79{
80public:
82
84 Profiler() { UpdateReferenceTime(); }
85
87 void NextFrame();
88
91 void Dump(const string_view &inTag = string_view());
92
94 void AddThread(ProfileThread *inThread);
95
97 void RemoveThread(ProfileThread *inThread);
98
101
102private:
104 struct ThreadSamples
105 {
106 String mThreadName;
107 ProfileSample * mSamplesBegin;
108 ProfileSample * mSamplesEnd;
109 };
110
112 class Aggregator
113 {
114 public:
116 Aggregator(const char *inName) : mName(inName) { }
117
119 void AccumulateMeasurement(uint64 inCyclesInCallWithChildren)
120 {
121 mCallCounter++;
122 mTotalCyclesInCallWithChildren += inCyclesInCallWithChildren;
123 mMinCyclesInCallWithChildren = min(inCyclesInCallWithChildren, mMinCyclesInCallWithChildren);
124 mMaxCyclesInCallWithChildren = max(inCyclesInCallWithChildren, mMaxCyclesInCallWithChildren);
125 }
126
128 bool operator < (const Aggregator &inRHS) const
129 {
130 return mTotalCyclesInCallWithChildren > inRHS.mTotalCyclesInCallWithChildren;
131 }
132
134 const char * mName;
135
137 uint32 mCallCounter = 0;
138 uint64 mTotalCyclesInCallWithChildren = 0;
139 uint64 mMinCyclesInCallWithChildren = 0xffffffffffffffffUL;
140 uint64 mMaxCyclesInCallWithChildren = 0;
141 };
142
143 using Threads = Array<ThreadSamples>;
144 using Aggregators = Array<Aggregator>;
145 using KeyToAggregator = UnorderedMap<const char *, size_t>;
146
148 static void sAggregate(int inDepth, uint32 inColor, ProfileSample *&ioSample, const ProfileSample *inEnd, Aggregators &ioAggregators, KeyToAggregator &ioKeyToAggregator);
149
151 void UpdateReferenceTime();
152
154 uint64 GetProcessorTicksPerSecond() const;
155
157 void DumpInternal();
158 void DumpChart(const char *inTag, const Threads &inThreads, const KeyToAggregator &inKeyToAggregators, const Aggregators &inAggregators);
159
160 std::mutex mLock;
161 uint64 mReferenceTick;
162 std::chrono::high_resolution_clock::time_point mReferenceTime;
163 Array<ProfileThread *> mThreads;
164 bool mDump = false;
165 String mDumpTag;
166};
167
168// Class that contains the information of a single scoped measurement
170{
171public:
173
174 const char * mName;
177 uint8 mUnused[3];
180};
181
184{
185public:
187
189 inline ProfileThread(const string_view &inThreadName);
190 inline ~ProfileThread();
191
192 static const uint cMaxSamples = 65536;
193
197
198#ifdef JPH_SHARED_LIBRARY
199 JPH_EXPORT static void sSetInstance(ProfileThread *inInstance);
201#else
202 static inline void sSetInstance(ProfileThread *inInstance) { sInstance = inInstance; }
203 static inline ProfileThread *sGetInstance() { return sInstance; }
204
205private:
206 static thread_local ProfileThread *sInstance;
207#endif
208};
209
212{
213public:
215 inline ProfileMeasurement(const char *inName, uint32 inColor = 0);
216 inline ~ProfileMeasurement();
217
218private:
219 ProfileSample * mSample;
220 ProfileSample mTemp;
221
222 static bool sOutOfSamplesReported;
223};
224
226
227#include "Profiler.inl"
228
230// Macros to do the actual profiling
232
233JPH_SUPPRESS_WARNING_PUSH
234JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
235
236
237#define JPH_PROFILE_START(name) do { Profiler::sInstance = new Profiler; JPH_PROFILE_THREAD_START(name); } while (false)
238
240#define JPH_PROFILE_END() do { JPH_PROFILE_THREAD_END(); delete Profiler::sInstance; Profiler::sInstance = nullptr; } while (false)
241
243#define JPH_PROFILE_THREAD_START(name) do { if (Profiler::sInstance) ProfileThread::sSetInstance(new ProfileThread(name)); } while (false)
244
246#define JPH_PROFILE_THREAD_END() do { delete ProfileThread::sGetInstance(); ProfileThread::sSetInstance(nullptr); } while (false)
247
249#define JPH_PROFILE_TAG2(line) profile##line
250#define JPH_PROFILE_TAG(line) JPH_PROFILE_TAG2(line)
251#define JPH_PROFILE(...) ProfileMeasurement JPH_PROFILE_TAG(__LINE__)(__VA_ARGS__)
252
254#define JPH_PROFILE_FUNCTION() JPH_PROFILE(JPH_FUNCTION_NAME)
255
257#define JPH_PROFILE_NEXTFRAME() Profiler::sInstance->NextFrame()
258
260#define JPH_PROFILE_DUMP(...) Profiler::sInstance->Dump(__VA_ARGS__)
261
262JPH_SUPPRESS_WARNING_POP
263
264#else
265
267// Dummy profiling instructions
269
270JPH_SUPPRESS_WARNING_PUSH
271JPH_CLANG_SUPPRESS_WARNING("-Wc++98-compat-pedantic")
272
273#define JPH_PROFILE_START(name)
274#define JPH_PROFILE_END()
275#define JPH_PROFILE_THREAD_START(name)
276#define JPH_PROFILE_THREAD_END()
277#define JPH_PROFILE(...)
278#define JPH_PROFILE_FUNCTION()
279#define JPH_PROFILE_NEXTFRAME()
280#define JPH_PROFILE_DUMP(...)
281
282JPH_SUPPRESS_WARNING_POP
283
284#endif
std::uint8_t uint8
Definition: Core.h:440
#define JPH_EXPORT
Definition: Core.h:227
#define JPH_SUPPRESS_WARNINGS_STD_BEGIN
Definition: Core.h:372
#define JPH_SUPPRESS_WARNINGS_STD_END
Definition: Core.h:384
std::uint64_t uint64
Definition: Core.h:443
unsigned int uint
Definition: Core.h:439
#define JPH_NAMESPACE_END
Definition: Core.h:367
#define JPH_CLANG_SUPPRESS_WARNING(w)
Definition: Core.h:254
std::uint32_t uint32
Definition: Core.h:442
#define JPH_EXPORT_GCC_BUG_WORKAROUND
Definition: Core.h:231
#define JPH_NAMESPACE_BEGIN
Definition: Core.h:361
#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:212
Definition: Profiler.h:170
uint32 mColor
Color to use for this sample.
Definition: Profiler.h:175
uint64 mEndCycle
Cycle counter at end of measurement.
Definition: Profiler.h:179
JPH_OVERRIDE_NEW_DELETE const char * mName
User defined name of this item.
Definition: Profiler.h:174
uint8 mDepth
Calculated depth.
Definition: Profiler.h:176
uint64 mStartCycle
Cycle counter at start of measurement.
Definition: Profiler.h:178
Collects all samples of a single thread.
Definition: Profiler.h:184
ProfileSample mSamples[cMaxSamples]
Buffer of samples.
Definition: Profiler.h:195
uint mCurrentSample
Next position to write a sample to.
Definition: Profiler.h:196
~ProfileThread()
Definition: Profiler.inl:17
static ProfileThread * sGetInstance()
Definition: Profiler.h:203
String mThreadName
Name of the thread that we're collecting information for.
Definition: Profiler.h:194
static void sSetInstance(ProfileThread *inInstance)
Definition: Profiler.h:202
static const uint cMaxSamples
Definition: Profiler.h:192
Singleton class for managing profiling information.
Definition: Profiler.h:79
JPH_OVERRIDE_NEW_DELETE Profiler()
Constructor.
Definition: Profiler.h:84
static Profiler * sInstance
Singleton instance.
Definition: Profiler.h:100