diff --git a/dqn_debug.h b/dqn_debug.h index 9bab413..ba765ca 100644 --- a/dqn_debug.h +++ b/dqn_debug.h @@ -2,8 +2,8 @@ #define DQN_ASAN_POISON 0 #endif -#if !defined(DQN_ASAN_POISON_VET) - #define DQN_ASAN_POISON_VET 0 +#if !defined(DQN_ASAN_VET_POISON) + #define DQN_ASAN_VET_POISON 0 #endif #define DQN_ASAN_POISON_ALIGNMENT 8 diff --git a/dqn_helpers.cpp b/dqn_helpers.cpp index 82466cf..42d2546 100644 --- a/dqn_helpers.cpp +++ b/dqn_helpers.cpp @@ -952,9 +952,9 @@ DQN_API void Dqn_Library_DumpThreadContextArenaStat(Dqn_String8 file_path) #if !defined(DQN_NO_PROFILER) // NOTE: [$PROF] Dqn_Profiler ====================================================================== -Dqn_ProfilerZoneScope::Dqn_ProfilerZoneScope(uint16_t label) +Dqn_ProfilerZoneScope::Dqn_ProfilerZoneScope(Dqn_String8 name, uint16_t anchor_index) { - zone = Dqn_Profiler_BeginZone(label); + zone = Dqn_Profiler_BeginZoneWithIndex(name, anchor_index); } Dqn_ProfilerZoneScope::~Dqn_ProfilerZoneScope() @@ -962,15 +962,16 @@ Dqn_ProfilerZoneScope::~Dqn_ProfilerZoneScope() Dqn_Profiler_EndZone(zone); } -Dqn_ProfilerZone Dqn_Profiler_BeginZone(uint16_t label) +Dqn_ProfilerZone Dqn_Profiler_BeginZoneWithIndex(Dqn_String8 name, uint16_t anchor_index) { - Dqn_ProfilerAnchor *anchor = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back) + label; + Dqn_ProfilerAnchor *anchor = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back) + anchor_index; + anchor->name = name; Dqn_ProfilerZone result = {}; result.begin_tsc = Dqn_CPU_TSC(); - result.label = label; + result.anchor_index = anchor_index; result.parent_zone = g_dqn_library->profiler->parent_zone; result.elapsed_tsc_at_zone_start = anchor->tsc_inclusive; - g_dqn_library->profiler->parent_zone = label; + g_dqn_library->profiler->parent_zone = anchor_index; return result; } @@ -978,15 +979,15 @@ void Dqn_Profiler_EndZone(Dqn_ProfilerZone zone) { uint64_t elapsed_tsc = Dqn_CPU_TSC() - zone.begin_tsc; Dqn_ProfilerAnchor *anchor_buffer = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back); - Dqn_ProfilerAnchor *anchor = anchor_buffer + zone.label; + Dqn_ProfilerAnchor *anchor = anchor_buffer + zone.anchor_index; anchor->hit_count++; anchor->tsc_inclusive = zone.elapsed_tsc_at_zone_start + elapsed_tsc; anchor->tsc_exclusive += elapsed_tsc; - Dqn_ProfilerAnchor *parent_anchor = anchor_buffer + zone.parent_zone; - parent_anchor->tsc_exclusive -= elapsed_tsc; - g_dqn_library->profiler->parent_zone = zone.parent_zone; + Dqn_ProfilerAnchor *parent_anchor = anchor_buffer + zone.parent_zone; + parent_anchor->tsc_exclusive -= elapsed_tsc; + g_dqn_library->profiler->parent_zone = zone.parent_zone; } Dqn_ProfilerAnchor *Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer buffer) @@ -1003,4 +1004,31 @@ void Dqn_Profiler_SwapAnchorBuffer(uint32_t anchor_count) Dqn_ProfilerAnchor *anchors = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back); DQN_MEMSET(anchors, 0, anchor_count * sizeof(g_dqn_library->profiler->anchors[0][0])); } + +void Dqn_Profiler_Dump(uint64_t tsc_per_second) +{ + Dqn_ProfilerAnchor *anchors = Dqn_Profiler_AnchorBuffer(Dqn_ProfilerAnchorBuffer_Back); + for (size_t anchor_index = 1; anchor_index < DQN_PROFILER_ANCHOR_BUFFER_SIZE; anchor_index++) { + Dqn_ProfilerAnchor const *anchor = anchors + anchor_index; + if (!anchor->hit_count) + continue; + + uint64_t tsc_exclusive = anchor->tsc_exclusive; + uint64_t tsc_inclusive = anchor->tsc_inclusive; + Dqn_f64 tsc_exclusive_milliseconds = tsc_exclusive * 1000 / DQN_CAST(Dqn_f64)tsc_per_second; + if (tsc_exclusive == tsc_inclusive) { + Dqn_Print_LnF("%.*s[%u]: %.1fms", + DQN_STRING_FMT(anchor->name), + anchor->hit_count, + tsc_exclusive_milliseconds); + } else { + Dqn_f64 tsc_inclusive_milliseconds = tsc_inclusive * 1000 / DQN_CAST(Dqn_f64)tsc_per_second; + Dqn_Print_LnF("%.*s[%u]: %.1f/%.1fms", + DQN_STRING_FMT(anchor->name), + anchor->hit_count, + tsc_exclusive_milliseconds, + tsc_inclusive_milliseconds); + } + } +} #endif // !defined(DQN_NO_PROFILER) diff --git a/dqn_helpers.h b/dqn_helpers.h index 57dd0fd..c76d533 100644 --- a/dqn_helpers.h +++ b/dqn_helpers.h @@ -489,7 +489,7 @@ DQN_API Dqn_U64String Dqn_U64ToString (uint64_t val, char separator); for (size_t index = 0; index < Zone_Count; index++) { Dqn_ProfilerAnchor *anchor = anchors + index; printf("%.*s[%u] %zu cycles (%.1fms)\n", - DQN_STRING_FMT(anchor->label), + DQN_STRING_FMT(anchor->anchor_index), anchor->hit_count, anchor->tsc_inclusive, anchor->tsc_inclusive * tsc_per_seconds * 1000.f); @@ -524,27 +524,29 @@ struct Dqn_ProfilerAnchor // time spent in children functions that we call that are also being // profiled. If we recursively call into ourselves, the time we spent in // our function is accumulated. - uint64_t tsc_inclusive; - uint64_t tsc_exclusive; - uint16_t hit_count; + uint64_t tsc_inclusive; + uint64_t tsc_exclusive; + uint16_t hit_count; + Dqn_String8 name; }; struct Dqn_ProfilerZone { - uint16_t label; - uint64_t begin_tsc; - uint16_t parent_zone; - uint64_t elapsed_tsc_at_zone_start; + uint16_t anchor_index; + uint64_t begin_tsc; + uint16_t parent_zone; + uint64_t elapsed_tsc_at_zone_start; }; #if defined(__cplusplus) struct Dqn_ProfilerZoneScope { - Dqn_ProfilerZoneScope(uint16_t label); + Dqn_ProfilerZoneScope(Dqn_String8 name, uint16_t anchor_index); ~Dqn_ProfilerZoneScope(); Dqn_ProfilerZone zone; }; -#define Dqn_Profiler_ZoneScope(label) auto DQN_UNIQUE_NAME(profile_zone_##label_) = Dqn_ProfilerZoneScope(label) +#define Dqn_Profiler_ZoneScope(name) auto DQN_UNIQUE_NAME(profile_zone_) = Dqn_ProfilerZoneScope(DQN_STRING8(name), __COUNTER__ + 1) +#define Dqn_Profiler_ZoneScopeWithIndex(name, anchor_index) auto DQN_UNIQUE_NAME(profile_zone_) = Dqn_ProfilerZoneScope(DQN_STRING8(name), anchor_index) #endif enum Dqn_ProfilerAnchorBuffer @@ -560,10 +562,15 @@ struct Dqn_Profiler uint16_t parent_zone; }; -Dqn_ProfilerZone Dqn_Profiler_BeginZone (uint16_t label); -void Dqn_Profiler_EndZone (Dqn_ProfilerZone zone); -Dqn_ProfilerAnchor *Dqn_Profiler_AnchorBuffer (Dqn_ProfilerAnchorBuffer buffer); -void Dqn_Profiler_SwapAnchorBuffer (uint32_t anchor_count); +// NOTE: Macros ==================================================================================== +#define Dqn_Profiler_BeginZone(name) Dqn_Profiler_BeginZoneWithIndex(DQN_STRING8(name), __COUNTER__ + 1) + +// NOTE: API ======================================================================================= +Dqn_ProfilerZone Dqn_Profiler_BeginZoneWithIndex(Dqn_String8 name, uint16_t anchor_index); +void Dqn_Profiler_EndZone (Dqn_ProfilerZone zone); +Dqn_ProfilerAnchor *Dqn_Profiler_AnchorBuffer (Dqn_ProfilerAnchorBuffer buffer); +void Dqn_Profiler_SwapAnchorBuffer (uint32_t anchor_count); +void Dqn_Profiler_Dump (uint64_t tsc_per_second); #endif // !defined(DQN_NO_PROFILER) // NOTE: [$DLIB] Dqn_Library ======================================================================= diff --git a/dqn_memory.cpp b/dqn_memory.cpp index c984d65..142c6fd 100644 --- a/dqn_memory.cpp +++ b/dqn_memory.cpp @@ -179,8 +179,8 @@ DQN_API Dqn_MemBlockSizeRequiredResult Dqn_MemBlock_SizeRequired(Dqn_MemBlock co Dqn_usize Dqn_MemBlock_MetadataSize() { Dqn_usize init_poison_page = DQN_ASAN_POISON ? DQN_ASAN_POISON_GUARD_SIZE : 0; - Dqn_usize poison_alignment = DQN_ASAN_POISON ? DQN_ASAN_POISON_ALIGNMENT : 0; - Dqn_usize result = Dqn_AlignUpPowerOfTwo(sizeof(Dqn_MemBlock), poison_alignment) + init_poison_page; + Dqn_usize alignment = DQN_ASAN_POISON ? DQN_ASAN_POISON_ALIGNMENT : alignof(Dqn_MemBlock); + Dqn_usize result = Dqn_AlignUpPowerOfTwo(sizeof(Dqn_MemBlock), alignment) + init_poison_page; return result; }