group2 0.1.0
CSE 125 Group 2
Loading...
Searching...
No Matches
Profiler.hpp
Go to the documentation of this file.
1
33
34#pragma once
35
36#include <SDL3/SDL.h>
37
38#include <array>
39#include <atomic>
40#include <cstdint>
41#include <functional>
42#include <limits>
43
44namespace group2::perf
45{
46
50inline constexpr std::size_t k_maxScopes = 64;
51
56inline constexpr std::size_t k_histogramBuckets = 32;
57
59using ScopeId = std::uint16_t;
60inline constexpr ScopeId k_invalidScope = static_cast<ScopeId>(-1);
61
66ScopeId registerScope(const char* name);
67
70const char* scopeName(ScopeId id);
71
73std::size_t scopeCount();
74
77{
78 std::atomic<std::uint64_t> count{0};
79 std::atomic<std::uint64_t> sumTicks{0};
80 std::atomic<std::uint64_t> minTicks{std::numeric_limits<std::uint64_t>::max()};
81 std::atomic<std::uint64_t> maxTicks{0};
82 std::array<std::atomic<std::uint32_t>, k_histogramBuckets> hist{};
83};
84
88{
89 std::atomic<std::uint64_t> bytesSent{0};
90 std::atomic<std::uint64_t> bytesRecv{0};
91 std::atomic<std::uint64_t> snapshotsSent{0};
92 std::atomic<std::uint64_t> packetsSent{0};
93 std::atomic<std::uint64_t> packetsRecv{0};
94 std::atomic<std::uint32_t> peakBacklog{0};
95 std::atomic<std::uint32_t> clientCount{0};
96};
97
100{
103 {
104 const char* name = "";
105 std::uint64_t count = 0;
106 std::uint64_t minNs = 0;
107 std::uint64_t p50Ns = 0;
108 std::uint64_t p99Ns = 0;
109 std::uint64_t maxNs = 0;
110 std::uint64_t meanNs = 0;
111 };
112
113 std::array<ScopeSummary, k_maxScopes> scopes{};
114 std::size_t scopeNum = 0;
115
117 std::uint64_t tickCount = 0;
118 std::uint64_t tickSumNs = 0;
119 std::uint64_t tickMaxNs = 0;
120 std::uint64_t tickP99Ns = 0;
121
123 std::uint64_t bytesSent = 0;
124 std::uint64_t bytesRecv = 0;
125 std::uint64_t snapshotsSent = 0;
126 std::uint64_t packetsSent = 0;
127 std::uint64_t packetsRecv = 0;
128 std::uint32_t peakBacklog = 0;
129 std::uint32_t clientCount = 0;
130
132 std::uint64_t windowStartMs = 0;
133 std::uint64_t windowEndMs = 0;
134};
135
139extern std::atomic<bool> enabled;
140
147void initFromEnv();
148
153void startAggregator(std::function<void(const Snapshot&)> cb);
154
156void stopAggregator();
157
160void recordSample(ScopeId id, std::uint64_t ticks) noexcept;
161
163void tickEnd(std::uint64_t tickWallNs) noexcept;
164
167{
168 static NetworkCounters c;
169 return c;
170}
171
173inline std::uint64_t ticksToNs(std::uint64_t ticks) noexcept
174{
175 static const std::uint64_t k_freq = SDL_GetPerformanceFrequency();
176 // `ticks * 1e9 / freq` with intermediate clamp to avoid overflow at
177 // ~18.4 s on a 1 GHz counter. We never measure that long.
178 return (ticks / k_freq) * 1'000'000'000ULL + ((ticks % k_freq) * 1'000'000'000ULL) / k_freq;
179}
180
184{
185public:
186 explicit ScopeTimer(ScopeId id) noexcept : scopeId(id), recording(enabled.load(std::memory_order_relaxed))
187 {
188 if (recording)
189 startCounter = SDL_GetPerformanceCounter();
190 }
191 ~ScopeTimer() noexcept
192 {
193 if (!recording)
194 return;
195 const std::uint64_t end = SDL_GetPerformanceCounter();
197 }
198
199 ScopeTimer(const ScopeTimer&) = delete;
200 ScopeTimer& operator=(const ScopeTimer&) = delete;
203
204private:
206 bool recording{false};
207 std::uint64_t startCounter{0};
208};
209
210} // namespace group2::perf
211
212// ────────────────────────────────────────────────────────────────────
213// Macros
214// ────────────────────────────────────────────────────────────────────
215
217#define GROUP2_PROF_CAT2(a, b) a##b
218#define GROUP2_PROF_CAT(a, b) GROUP2_PROF_CAT2(a, b)
220
238#define GROUP2_PROF_SCOPE(label) \
239 ::group2::perf::ScopeTimer GROUP2_PROF_CAT(_gpScope, __LINE__) \
240 { \
241 []() noexcept -> ::group2::perf::ScopeId { \
242 static const ::group2::perf::ScopeId k_id = ::group2::perf::registerScope(label); \
243 return k_id; \
244 }() \
245 }
ScopeTimer(ScopeId id) noexcept
Definition Profiler.hpp:186
std::uint64_t startCounter
Definition Profiler.hpp:207
ScopeTimer(const ScopeTimer &)=delete
ScopeId scopeId
Definition Profiler.hpp:205
bool recording
Definition Profiler.hpp:206
~ScopeTimer() noexcept
Definition Profiler.hpp:191
ScopeTimer & operator=(const ScopeTimer &)=delete
ScopeTimer & operator=(ScopeTimer &&)=delete
ScopeTimer(ScopeTimer &&)=delete
Definition Parallel.hpp:43
constexpr std::size_t k_histogramBuckets
Histogram bucket count.
Definition Profiler.hpp:56
void initFromEnv()
Initialize from environment variables.
Definition Profiler.cpp:255
std::uint64_t ticksToNs(std::uint64_t ticks) noexcept
Convenience: convert SDL performance-counter ticks to nanoseconds.
Definition Profiler.hpp:173
std::size_t scopeCount()
Returns the highest registered id + 1.
Definition Profiler.cpp:217
constexpr std::size_t k_maxScopes
Compile-time caps.
Definition Profiler.hpp:50
void recordSample(ScopeId id, std::uint64_t ticks) noexcept
Recording entry point — public so unit tests can invoke it directly without a real ScopeTimer.
Definition Profiler.cpp:222
constexpr ScopeId k_invalidScope
Definition Profiler.hpp:60
void startAggregator(std::function< void(const Snapshot &)> cb)
Spawn the 1 Hz aggregator thread.
Definition Profiler.cpp:263
void tickEnd(std::uint64_t tickWallNs) noexcept
Tick boundary marker — call once per server tick() end.
Definition Profiler.cpp:242
ScopeId registerScope(const char *name)
Register (or look up) a scope name and return its dense id.
Definition Profiler.cpp:189
void stopAggregator()
Stop the aggregator and join its thread. Idempotent.
Definition Profiler.cpp:286
std::atomic< bool > enabled
Master switch.
Definition Profiler.cpp:187
std::uint16_t ScopeId
Dense small id used to index the global stats table.
Definition Profiler.hpp:59
NetworkCounters & net()
Network counter accessor. Hot-path code increments these directly.
Definition Profiler.hpp:166
const char * scopeName(ScopeId id)
Returns the human-readable name a ScopeId was registered with, or "" if id is out of range.
Definition Profiler.cpp:209
Per-tick network counters maintained by the network code.
Definition Profiler.hpp:88
std::atomic< std::uint32_t > peakBacklog
Definition Profiler.hpp:94
std::atomic< std::uint64_t > bytesSent
Definition Profiler.hpp:89
std::atomic< std::uint32_t > clientCount
Definition Profiler.hpp:95
std::atomic< std::uint64_t > packetsSent
Definition Profiler.hpp:92
std::atomic< std::uint64_t > bytesRecv
Definition Profiler.hpp:90
std::atomic< std::uint64_t > snapshotsSent
Definition Profiler.hpp:91
std::atomic< std::uint64_t > packetsRecv
Definition Profiler.hpp:93
Per-scope, all-thread atomic counters.
Definition Profiler.hpp:77
std::atomic< std::uint64_t > maxTicks
Definition Profiler.hpp:81
std::array< std::atomic< std::uint32_t >, k_histogramBuckets > hist
Definition Profiler.hpp:82
std::atomic< std::uint64_t > minTicks
Definition Profiler.hpp:80
std::atomic< std::uint64_t > count
Definition Profiler.hpp:78
std::atomic< std::uint64_t > sumTicks
Definition Profiler.hpp:79
Per-scope summary, filled for [0, scopeCount).
Definition Profiler.hpp:103
std::uint64_t p50Ns
Definition Profiler.hpp:107
std::uint64_t count
Definition Profiler.hpp:105
std::uint64_t maxNs
Definition Profiler.hpp:109
const char * name
Definition Profiler.hpp:104
std::uint64_t p99Ns
Definition Profiler.hpp:108
std::uint64_t meanNs
Definition Profiler.hpp:110
std::uint64_t minNs
Definition Profiler.hpp:106
Globally-visible snapshot returned to the aggregator callback.
Definition Profiler.hpp:100
std::uint64_t bytesRecv
Definition Profiler.hpp:124
std::uint64_t packetsSent
Definition Profiler.hpp:126
std::uint64_t bytesSent
Network totals over the window.
Definition Profiler.hpp:123
std::uint64_t snapshotsSent
Definition Profiler.hpp:125
std::uint64_t tickP99Ns
Definition Profiler.hpp:120
std::uint64_t windowEndMs
Definition Profiler.hpp:133
std::uint64_t tickMaxNs
Definition Profiler.hpp:119
std::size_t scopeNum
Definition Profiler.hpp:114
std::uint32_t peakBacklog
Definition Profiler.hpp:128
std::uint64_t packetsRecv
Definition Profiler.hpp:127
std::array< ScopeSummary, k_maxScopes > scopes
Definition Profiler.hpp:113
std::uint64_t windowStartMs
Wall-clock window covered (POSIX millis since epoch).
Definition Profiler.hpp:132
std::uint32_t clientCount
Definition Profiler.hpp:129
std::uint64_t tickCount
Per-tick wall time over the aggregation window.
Definition Profiler.hpp:117
std::uint64_t tickSumNs
Definition Profiler.hpp:118