From f4df9013bb1275ba6389953a66cda28ebd8b7210 Mon Sep 17 00:00:00 2001 From: Bartosz Taudul Date: Mon, 21 Oct 2024 17:32:54 +0200 Subject: [PATCH] Add memory discard message. This can be used to erase all allocations made within the named memory pool. The usual use case would be for arena allocators, which allocate by advancing a pointer and never have to free the memory. There is no tracking of individual allocations and everything is freed frequently, by reseting the pointer, for example once per frame. Since this is used in special-purpose allocators, there is no support for discarding the memory of the default memory pool. --- public/client/TracyProfiler.cpp | 9 +++++++ public/client/TracyProfiler.hpp | 46 +++++++++++++++++++++++++++++++++ public/common/TracyProtocol.hpp | 2 +- public/common/TracyQueue.hpp | 12 +++++++++ public/tracy/Tracy.hpp | 12 +++++++++ 5 files changed, 80 insertions(+), 1 deletion(-) diff --git a/public/client/TracyProfiler.cpp b/public/client/TracyProfiler.cpp index 84c246f2..d228486d 100644 --- a/public/client/TracyProfiler.cpp +++ b/public/client/TracyProfiler.cpp @@ -2862,6 +2862,15 @@ Profiler::DequeueStatus Profiler::DequeueSerial() MemWrite( &item->memFree.time, dt ); break; } + case QueueType::MemDiscard: + case QueueType::MemDiscardCallstack: + { + int64_t t = MemRead( &item->memDiscard.time ); + int64_t dt = t - refSerial; + refSerial = t; + MemWrite( &item->memDiscard.time, dt ); + break; + } case QueueType::GpuZoneBeginSerial: case QueueType::GpuZoneBeginCallstackSerial: { diff --git a/public/client/TracyProfiler.hpp b/public/client/TracyProfiler.hpp index 38dd90c6..6105b9da 100644 --- a/public/client/TracyProfiler.hpp +++ b/public/client/TracyProfiler.hpp @@ -633,6 +633,40 @@ public: #endif } + static tracy_force_inline void MemDiscard( const char* name, bool secure ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +#endif + const auto thread = GetThreadHandle(); + + GetProfiler().m_serialLock.lock(); + SendMemDiscard( QueueType::MemDiscard, thread, name ); + GetProfiler().m_serialLock.unlock(); + } + + static tracy_force_inline void MemDiscardCallstack( const char* name, bool secure, int depth ) + { + if( secure && !ProfilerAvailable() ) return; +#ifdef TRACY_HAS_CALLSTACK +# ifdef TRACY_ON_DEMAND + if( !GetProfiler().IsConnected() ) return; +# endif + const auto thread = GetThreadHandle(); + + auto callstack = Callstack( depth ); + + GetProfiler().m_serialLock.lock(); + SendCallstackSerial( callstack ); + SendMemDiscard( QueueType::MemDiscard, thread, name ); + GetProfiler().m_serialLock.unlock(); +#else + static_cast(depth); // unused + MemDiscard( name, secure ); +#endif + } + static tracy_force_inline void SendCallstack( int depth ) { #ifdef TRACY_HAS_CALLSTACK @@ -922,6 +956,18 @@ private: GetProfiler().m_serialQueue.commit_next(); } + static tracy_force_inline void SendMemDiscard( QueueType type, const uint32_t thread, const char* name ) + { + assert( type == QueueType::MemDiscard || type == QueueType::MemDiscardCallstack ); + + auto item = GetProfiler().m_serialQueue.prepare_next(); + MemWrite( &item->hdr.type, type ); + MemWrite( &item->memDiscard.time, GetTime() ); + MemWrite( &item->memDiscard.thread, thread ); + MemWrite( &item->memDiscard.name, (uint64_t)name ); + GetProfiler().m_serialQueue.commit_next(); + } + static tracy_force_inline void SendMemName( const char* name ) { assert( name ); diff --git a/public/common/TracyProtocol.hpp b/public/common/TracyProtocol.hpp index 8f72d762..839c24e8 100644 --- a/public/common/TracyProtocol.hpp +++ b/public/common/TracyProtocol.hpp @@ -9,7 +9,7 @@ namespace tracy constexpr unsigned Lz4CompressBound( unsigned isize ) { return isize + ( isize / 255 ) + 16; } -enum : uint32_t { ProtocolVersion = 71 }; +enum : uint32_t { ProtocolVersion = 72 }; enum : uint16_t { BroadcastVersion = 3 }; using lz4sz_t = uint32_t; diff --git a/public/common/TracyQueue.hpp b/public/common/TracyQueue.hpp index b17d9a41..c681698a 100644 --- a/public/common/TracyQueue.hpp +++ b/public/common/TracyQueue.hpp @@ -42,6 +42,8 @@ enum class QueueType : uint8_t MemAllocCallstackNamed, MemFreeCallstack, MemFreeCallstackNamed, + MemDiscard, + MemDiscardCallstack, GpuZoneBegin, GpuZoneBeginCallstack, GpuZoneBeginAllocSrcLoc, @@ -502,6 +504,13 @@ struct QueueMemFree uint64_t ptr; }; +struct QueueMemDiscard +{ + int64_t time; + uint32_t thread; + uint64_t name; +}; + struct QueueCallstackFat { uint64_t ptr; @@ -742,6 +751,7 @@ struct QueueItem QueueGpuContextNameFat gpuContextNameFat; QueueMemAlloc memAlloc; QueueMemFree memFree; + QueueMemDiscard memDiscard; QueueMemNamePayload memName; QueueThreadGroupHint threadGroupHint; QueueCallstackFat callstackFat; @@ -813,6 +823,8 @@ static constexpr size_t QueueDataSize[] = { sizeof( QueueHeader ) + sizeof( QueueMemAlloc ), // callstack, named sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack sizeof( QueueHeader ) + sizeof( QueueMemFree ), // callstack, named + sizeof( QueueHeader ) + sizeof( QueueMemDiscard ), + sizeof( QueueHeader ) + sizeof( QueueMemDiscard ), // callstack sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), sizeof( QueueHeader ) + sizeof( QueueGpuZoneBegin ), // callstack sizeof( QueueHeader ) + sizeof( QueueGpuZoneBeginLean ),// allocated source location diff --git a/public/tracy/Tracy.hpp b/public/tracy/Tracy.hpp index e75d02ce..5b19f683 100644 --- a/public/tracy/Tracy.hpp +++ b/public/tracy/Tracy.hpp @@ -75,8 +75,10 @@ #define TracyAlloc(x,y) #define TracyFree(x) +#define TracyMemoryDiscard(x) #define TracySecureAlloc(x,y) #define TracySecureFree(x) +#define TracySecureMemoryDiscard(x) #define TracyAllocN(x,y,z) #define TracyFreeN(x,y) @@ -98,8 +100,10 @@ #define TracyAllocS(x,y,z) #define TracyFreeS(x,y) +#define TracyMemoryDiscardS(x,y) #define TracySecureAllocS(x,y,z) #define TracySecureFreeS(x,y) +#define TracySecureMemoryDiscardS(x,y) #define TracyAllocNS(x,y,z,w) #define TracyFreeNS(x,y,z) @@ -206,8 +210,10 @@ # define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, false, name ) # define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, false, name ) +# define TracyMemoryDiscard( name ) tracy::Profiler::MemDiscardCallstack( name, false, TRACY_CALLSTACK ) # define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, TRACY_CALLSTACK, true, name ) # define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, TRACY_CALLSTACK, true, name ) +# define TracySecureMemoryDiscard( name ) tracy::Profiler::MemDiscardCallstack( name, true, TRACY_CALLSTACK ) #else # define TracyMessage( txt, size ) tracy::Profiler::Message( txt, size, 0 ) # define TracyMessageL( txt ) tracy::Profiler::Message( txt, 0 ) @@ -221,8 +227,10 @@ # define TracyAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, false, name ) # define TracyFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, false, name ) +# define TracyMemoryDiscard( name ) tracy::Profiler::MemDiscard( name, false ) # define TracySecureAllocN( ptr, size, name ) tracy::Profiler::MemAllocNamed( ptr, size, true, name ) # define TracySecureFreeN( ptr, name ) tracy::Profiler::MemFreeNamed( ptr, true, name ) +# define TracySecureMemoryDiscard( name ) tracy::Profiler::MemDiscard( name, true ) #endif #ifdef TRACY_HAS_CALLSTACK @@ -246,8 +254,10 @@ # define TracyAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, false, name ) # define TracyFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, false, name ) +# define TracyMemoryDiscardS( name, depth ) tracy::Profiler::MemDiscardCallstack( name, false, depth ) # define TracySecureAllocNS( ptr, size, depth, name ) tracy::Profiler::MemAllocCallstackNamed( ptr, size, depth, true, name ) # define TracySecureFreeNS( ptr, depth, name ) tracy::Profiler::MemFreeCallstackNamed( ptr, depth, true, name ) +# define TracySecureMemoryDiscardS( name, depth ) tracy::Profiler::MemDiscardCallstack( name, true, depth ) # define TracyMessageS( txt, size, depth ) tracy::Profiler::Message( txt, size, depth ) # define TracyMessageLS( txt, depth ) tracy::Profiler::Message( txt, depth ) @@ -274,8 +284,10 @@ # define TracyAllocNS( ptr, size, depth, name ) TracyAllocN( ptr, size, name ) # define TracyFreeNS( ptr, depth, name ) TracyFreeN( ptr, name ) +# define TracyMemoryDiscardS( name, depth ) tracy::Profiler::MemDiscard( name, false ) # define TracySecureAllocNS( ptr, size, depth, name ) TracySecureAllocN( ptr, size, name ) # define TracySecureFreeNS( ptr, depth, name ) TracySecureFreeN( ptr, name ) +# define TracySecureMemoryDiscardS( name, depth ) tracy::Profiler::MemDiscard( name, true ) # define TracyMessageS( txt, size, depth ) TracyMessage( txt, size ) # define TracyMessageLS( txt, depth ) TracyMessageL( txt )