Size: 7136
Comment:
|
← Revision 3 as of 2021-11-02 03:56:41 ⇥
Size: 7148
Comment:
|
Deletions are marked like this. | Additions are marked like this. |
Line 1: | Line 1: |
{{{C++ | {{{#!highlight c++ |
1 // Copyright Epic Games, Inc. All Rights Reserved.
2
3 #pragma once
4
5 #include "CoreTypes.h"
6 #include "Trace/Trace.h"
7 #include "Trace/Detail/Channel.h"
8 #include "Trace/Detail/Channel.inl"
9
10 #if !defined(CPUPROFILERTRACE_ENABLED)
11 #if UE_TRACE_ENABLED && !UE_BUILD_SHIPPING
12 #define CPUPROFILERTRACE_ENABLED 1
13 #else
14 #define CPUPROFILERTRACE_ENABLED 0
15 #endif
16 #endif
17
18 #if CPUPROFILERTRACE_ENABLED
19
20 UE_TRACE_CHANNEL_EXTERN(CpuChannel, CORE_API);
21
22 /*
23 * Facilities for tracing timed cpu events. Two types of events are supported, static events where the identifier is
24 * known at compile time, and dynamic event were identifiers can be constructed in runtime. Static events have lower overhead
25 * so always prefer to use them if possible.
26 *
27 * Events are tracked per thread, so begin/end calls must be matched and called on the same thread. It is possible to use any channel
28 * to emit the events, but both that channel and the CpuChannel must then be enabled.
29 *
30 * Usage of the scope macros is highly encouraged in order to avoid mistakes.
31 */
32 struct FCpuProfilerTrace
33 {
34 CORE_API static void Shutdown();
35 /*
36 * Output cpu event definition (spec).
37 * @param Name Event name
38 * @return Event definition id
39 */
40 FORCENOINLINE CORE_API static uint32 OutputEventType(const ANSICHAR* Name);
41 /*
42 * Output cpu event definition (spec).
43 * @param Name Event name
44 * @return Event definition id
45 */
46 FORCENOINLINE CORE_API static uint32 OutputEventType(const TCHAR* Name);
47 /*
48 * Output begin event marker for a given spec. Must always be matched with an end event.
49 * @param SpecId Event definition id.
50 */
51 CORE_API static void OutputBeginEvent(uint32 SpecId);
52 /*
53 * Output begin event marker for a dynamic event name. This is more expensive than statically known event
54 * names using \ref OutputBeginEvent. Must always be matched with an end event.
55 * @param Name Name of event
56 */
57 CORE_API static void OutputBeginDynamicEvent(const ANSICHAR* Name);
58 /*
59 * Output begin event marker for a dynamic event name. This is more expensive than statically known event
60 * names using \ref OutputBeginEvent. Must always be matched with an end event.
61 * @param Name Name of event
62 */
63 CORE_API static void OutputBeginDynamicEvent(const TCHAR* Name);
64 /*
65 * Output end event marker for static or dynamic event for the currently open scope.
66 */
67 CORE_API static void OutputEndEvent();
68
69 struct FEventScope
70 {
71 FEventScope(uint32 InSpecId, const Trace::FChannel& Channel)
72 : bEnabled(Channel | CpuChannel)
73 {
74 if (bEnabled)
75 {
76 OutputBeginEvent(InSpecId);
77 }
78 }
79
80 ~FEventScope()
81 {
82 if (bEnabled)
83 {
84 OutputEndEvent();
85 }
86 }
87
88 bool bEnabled;
89 };
90
91 struct FDynamicEventScope
92 {
93 FDynamicEventScope(const ANSICHAR* InEventName, const Trace::FChannel& Channel)
94 : bEnabled(Channel | CpuChannel)
95 {
96 if (bEnabled)
97 {
98 OutputBeginDynamicEvent(InEventName);
99 }
100 }
101
102 FDynamicEventScope(const TCHAR* InEventName, const Trace::FChannel& Channel)
103 : bEnabled(Channel | CpuChannel)
104 {
105 if (bEnabled)
106 {
107 OutputBeginDynamicEvent(InEventName);
108 }
109 }
110
111 ~FDynamicEventScope()
112 {
113 if (bEnabled)
114 {
115 OutputEndEvent();
116 }
117 }
118
119 bool bEnabled;
120 };
121 };
122
123 #define TRACE_CPUPROFILER_SHUTDOWN() \
124 FCpuProfilerTrace::Shutdown();
125
126 // Trace a scoped cpu timing event providing a static string (const ANSICHAR* or const TCHAR*)
127 // as the scope name and a trace channel.
128 // Example: TRACE_CPUPROFILER_EVENT_SCOPE_ON_CHANNEL_STR("My Scoped Timer A", CpuChannel)
129 // Note: The event will be emitted only if both the given channel and CpuChannel is enabled.
130 #define TRACE_CPUPROFILER_EVENT_SCOPE_ON_CHANNEL_STR(NameStr, Channel) \
131 static uint32 PREPROCESSOR_JOIN(__CpuProfilerEventSpecId, __LINE__); \
132 if (bool(Channel|CpuChannel) && PREPROCESSOR_JOIN(__CpuProfilerEventSpecId, __LINE__) == 0) { \
133 PREPROCESSOR_JOIN(__CpuProfilerEventSpecId, __LINE__) = FCpuProfilerTrace::OutputEventType(NameStr); \
134 } \
135 FCpuProfilerTrace::FEventScope PREPROCESSOR_JOIN(__CpuProfilerEventScope, __LINE__)(PREPROCESSOR_JOIN(__CpuProfilerEventSpecId, __LINE__), Channel);
136
137 // Trace a scoped cpu timing event providing a scope name (plain text) and a trace channel.
138 // Example: TRACE_CPUPROFILER_EVENT_SCOPE_ON_CHANNEL(MyScopedTimer::A, CpuChannel)
139 // Note: Do not use this macro with a static string because, in that case, additional quotes will
140 // be added around the event scope name.
141 // Note: The event will be emitted only if both the given channel and CpuChannel is enabled.
142 #define TRACE_CPUPROFILER_EVENT_SCOPE_ON_CHANNEL(Name, Channel) \
143 TRACE_CPUPROFILER_EVENT_SCOPE_ON_CHANNEL_STR(#Name, Channel)
144
145 // Trace a scoped cpu timing event providing a static string (const ANSICHAR* or const TCHAR*)
146 // as the scope name. It will use the Cpu trace channel.
147 // Example: TRACE_CPUPROFILER_EVENT_SCOPE_STR("My Scoped Timer A")
148 #define TRACE_CPUPROFILER_EVENT_SCOPE_STR(NameStr) \
149 TRACE_CPUPROFILER_EVENT_SCOPE_ON_CHANNEL_STR(NameStr, CpuChannel)
150
151 // Trace a scoped cpu timing event providing a scope name (plain text) and a trace channel.
152 // It will use the Cpu trace channel.
153 // Example: TRACE_CPUPROFILER_EVENT_SCOPE(MyScopedTimer::A)
154 // Note: Do not use this macro with a static string because, in that case, additional quotes will
155 // be added around the event scope name.
156 #define TRACE_CPUPROFILER_EVENT_SCOPE(Name) \
157 TRACE_CPUPROFILER_EVENT_SCOPE_ON_CHANNEL(Name, CpuChannel)
158
159 // Trace a scoped cpu timing event providing a dynamic string (const ANSICHAR* or const TCHAR*)
160 // as the scope name and a trace channel.
161 // Example: TRACE_CPUPROFILER_EVENT_SCOPE_TEXT_ON_CHANNEL(*MyScopedTimerNameString, CpuChannel)
162 // Note: This macro has a larger overhead compared to macro that accepts a plain text name
163 // or a static string. Use it only if scope name really needs to be a dynamic string.
164 #define TRACE_CPUPROFILER_EVENT_SCOPE_TEXT_ON_CHANNEL(Name, Channel) \
165 FCpuProfilerTrace::FDynamicEventScope PREPROCESSOR_JOIN(__CpuProfilerEventScope, __LINE__)(Name, Channel);
166
167 // Trace a scoped cpu timing event providing a dynamic string (const ANSICHAR* or const TCHAR*)
168 // as the scope name. It will use the Cpu trace channel.
169 // Example: TRACE_CPUPROFILER_EVENT_SCOPE_TEXT(*MyScopedTimerNameString)
170 // Note: This macro has a larger overhead compared to macro that accepts a plain text name
171 // or a static string. Use it only if scope name really needs to be a dynamic string.
172 #define TRACE_CPUPROFILER_EVENT_SCOPE_TEXT(Name) \
173 TRACE_CPUPROFILER_EVENT_SCOPE_TEXT_ON_CHANNEL(Name, CpuChannel)
174
175 #else
176
177 #define TRACE_CPUPROFILER_SHUTDOWN()
178 #define TRACE_CPUPROFILER_EVENT_SCOPE_ON_CHANNEL_STR(NameStr, Channel)
179 #define TRACE_CPUPROFILER_EVENT_SCOPE_ON_CHANNEL(Name, Channel)
180 #define TRACE_CPUPROFILER_EVENT_SCOPE_STR(NameStr)
181 #define TRACE_CPUPROFILER_EVENT_SCOPE(Name)
182 #define TRACE_CPUPROFILER_EVENT_SCOPE_TEXT_ON_CHANNEL(Name, Channel)
183 #define TRACE_CPUPROFILER_EVENT_SCOPE_TEXT(Name)
184
185 #endif
186