35 #ifndef HERMES_HERMES_COMMON_PROFILER_H
36 #define HERMES_HERMES_COMMON_PROFILER_H
39 #include <hermes/colors/argb_colors.h>
45 namespace hermes::profiler {
113 [[nodiscard]]
inline u64 begin() const noexcept {
return start_; }
116 [[nodiscard]]
inline u64 end() const noexcept {
return end_; }
119 [[nodiscard]]
inline u64 duration() const noexcept {
return end_ - start_; }
147 static const std::vector<Block> &
blockList();
188 static std::string
dump();
211 u64 profiler_start_time_{};
212 i64 cpu_frequency_{};
214 size_t max_block_count_{0};
215 u64 block_list_start_{0};
217 std::vector<BlockDescriptor *> block_descriptors_{};
218 std::vector<Block> block_list_;
219 std::stack<u32> block_stack_;
224 static inline u64 now() {
226 return static_cast<u64>(std::chrono::high_resolution_clock::now().time_since_epoch().count());
228 return static_cast<u64>(std::chrono::steady_clock::now().time_since_epoch().count());
230 #if (defined(__GNUC__) || defined(__ICC))
233 #if defined(__i386__)
235 __asm__
volatile(
"rdtsc" :
"=A"(ret));
237 #elif defined(__x86_64__) || defined(__amd64__)
239 __asm__
volatile(
"rdtsc" :
"=a"(low),
"=d"(high));
240 return (high << 32) | low;
247 static inline u64 ns2ticks(
u64 ns) {
253 static inline u64 us2ticks(
u64 us) {
259 static inline u64 ms2ticks(
u64 ms) {
265 static inline u64 s2ticks(
u64 s) {
271 static inline u64 ticks2ns(
u64 ticks) {
279 static inline u64 ticks2us(
u64 ticks) {
287 static inline u64 ticks2ms(
u64 ticks) {
295 static inline u64 ticks2s(
u64 ticks) {
302 static inline i64 computeCPUFrequency() {
303 return std::chrono::high_resolution_clock::period::den / std::chrono::high_resolution_clock::period::num;
305 #define HERMES_PROFILE_ENABLED
307 #ifdef HERMES_PROFILE_ENABLED
313 template<
class ... TArgs>
318 inline constexpr
u32 extract_color<>() {
319 return hermes::argb_colors::Default;
326 return hermes::argb_colors::Default;
332 inline constexpr
u32 extract_color<u32>(
u32 _color) {
340 template<
class ... TArgs>
349 template<
class T,
class ... TArgs>
359 #define HERMES_TOKEN_JOIN(x, y) x ## y
364 #define HERMES_TOKEN_CONCATENATE(x, y) HERMES_TOKEN_JOIN(x, y)
369 #define HERMES_PROFILE_START_BLOCK(name, ...) \
370 static u32 HERMES_TOKEN_CONCATENATE(hermes_block_desc_id_, __LINE__) = \
371 hermes::profiler::Profiler::pushBlockDescriptor(name, hermes::profiler::extract_color(__VA_ARGS__)); \
372 hermes::profiler::Profiler::Block HERMES_TOKEN_CONCATENATE(block, __LINE__)\
373 (HERMES_TOKEN_CONCATENATE(hermes_block_desc_id_, __LINE__)); \
374 hermes::profiler::Profiler::startBlock(HERMES_TOKEN_CONCATENATE(block, __LINE__))
377 #define HERMES_PROFILE_END_BLOCK hermes::profiler::Profiler::endBlock();
382 #define HERMES_PROFILE_SCOPE(name, ...) \
383 static u32 HERMES_TOKEN_CONCATENATE(hermes_block_desc_id_, __LINE__) = \
384 hermes::profiler::Profiler::pushBlockDescriptor(name, hermes::profiler::extract_color(__VA_ARGS__)); \
385 hermes::profiler::Profiler::ScopedBlock HERMES_TOKEN_CONCATENATE(block, __LINE__)\
386 (HERMES_TOKEN_CONCATENATE(hermes_block_desc_id_, __LINE__))
390 #define HERMES_PROFILE_FUNCTION(...) HERMES_PROFILE_SCOPE(__func__, ## __VA_ARGS__)
393 #define HERMES_ENABLE_PROFILER hermes::profiler::Profiler::enable();
396 #define HERMES_DISABLE_PROFILER hermes::profiler::Profiler::disable();
399 #define HERMES_RESET_PROFILER hermes::profiler::Profiler::reset();
Holds a labeled profiler block with start/end time points.
Definition: profiler.h:103
u32 descriptor_id
block descriptor identifier
Definition: profiler.h:121
u64 begin() const noexcept
block start time point (in ticks)
Definition: profiler.h:113
u64 duration() const noexcept
block duration (in ticks)
Definition: profiler.h:119
u32 level
profile stack level
Definition: profiler.h:122
u64 end() const noexcept
block end time point (in ticks)
Definition: profiler.h:116
RAII Profiler Block.
Definition: profiler.h:132
ScopedBlock(u32 block_descriptor_id)
Definition: profiler.cpp:186
Singleton code profiler.
Definition: profiler.h:83
static u32 pushBlockDescriptor(const char *name, u32 color=argb_colors::Default)
Registers a new block description.
Definition: profiler.cpp:45
static std::string dump()
Dumps profiling into a string.
Definition: profiler.cpp:91
static bool isEnabled()
Checks if Profiler is currently enabled.
Definition: profiler.cpp:127
static const std::vector< Block > & blockList()
Raw block data.
Definition: profiler.cpp:119
static i64 cpuFrequency()
Computed CPU frequency.
Definition: profiler.cpp:146
static u64 initTime()
Get time point when Profiler was instantiated.
Definition: profiler.cpp:142
static void enable()
Enables Profiler.
Definition: profiler.cpp:131
static void startBlock(Block &block)
Starts a new block by taking this call time point.
Definition: profiler.cpp:52
static void disable()
Disables Profiler.
Definition: profiler.cpp:135
static const BlockDescriptor & blockDescriptor(const Block &block)
Get block descriptor from block.
Definition: profiler.cpp:123
static void setMaxBlockCount(size_t max_block_count)
Sets a limit into the maximum number of stored blocks.
Definition: profiler.cpp:150
static void endBlock()
Finishes the block at the top of the stack.
Definition: profiler.cpp:74
static void reset()
Clears all blocks.
Definition: profiler.cpp:154
static void iterateBlocks(const std::function< void(const Block &)> &f)
Iterates over stored blocks sequentially.
Definition: profiler.cpp:160
uint64_t u64
64 bit size unsigned integer type
Definition: defs.h:89
uint32_t u32
32 bit size unsigned integer type
Definition: defs.h:88
int64_t i64
64 bit size integer type
Definition: defs.h:84
constexpr u32 extract_color(TArgs...)
Auxiliary function to pick variadic color argument.
Describes a block label.
Definition: profiler.h:86
u32 line
code line
Definition: profiler.h:98
BlockDescriptor(u32 id, u32 color, u32 line, const char *name)
Definition: profiler.cpp:35
const char * name
block name
Definition: profiler.h:99
u32 color
block color
Definition: profiler.h:96