diff options
author | ilezhankin <[email protected]> | 2025-05-20 12:34:52 +0300 |
---|---|---|
committer | ilezhankin <[email protected]> | 2025-05-20 12:48:53 +0300 |
commit | de92acc01b681316ac8231ed3f31bf4d85b2a05c (patch) | |
tree | 744022cb4194678d0ed223b78f545956f3e46a86 | |
parent | 21395e193baf5e561d5f33257a71fdd13a56f0f5 (diff) |
Add counter for wasted memory from TPagedBuffer in profiling mode
Пример графика с тестового кластера: <https://nda.ya.ru/t/RdGCM06J7EGx4P>
commit_hash:4cf9981cc6d7541487678a189386e8e7f091811d
-rw-r--r-- | yql/essentials/minikql/mkql_buffer.cpp | 25 | ||||
-rw-r--r-- | yql/essentials/minikql/mkql_buffer.h | 37 |
2 files changed, 48 insertions, 14 deletions
diff --git a/yql/essentials/minikql/mkql_buffer.cpp b/yql/essentials/minikql/mkql_buffer.cpp index c47b8648b25..b46a54e8f05 100644 --- a/yql/essentials/minikql/mkql_buffer.cpp +++ b/yql/essentials/minikql/mkql_buffer.cpp @@ -1,8 +1,15 @@ #include "mkql_buffer.h" -namespace NKikimr { +namespace NKikimr::NMiniKQL { -namespace NMiniKQL { +#if defined(PROFILE_MEMORY_ALLOCATIONS) +NMonitoring::TDynamicCounters::TCounterPtr TotalBytesWastedCounter; + +void InitializeGlobalPagedBufferCounters(::NMonitoring::TDynamicCounterPtr root) { + NMonitoring::TDynamicCounterPtr subGroup = root->GetSubgroup("counters", "utils")->GetSubgroup("subsystem", "mkqlalloc"); + TotalBytesWastedCounter = subGroup->GetCounter("PagedBuffer/TotalBytesWasted"); +} +#endif const size_t TBufferPage::PageCapacity = TBufferPage::PageAllocSize - sizeof(TBufferPage); @@ -14,10 +21,16 @@ TBufferPage* TBufferPage::Allocate() { throw std::bad_alloc(); } TBufferPage* result = ::new (ptr) TBufferPage(); +#if defined(PROFILE_MEMORY_ALLOCATIONS) + TotalBytesWastedCounter->Add(result->Wasted()); +#endif return result; } void TBufferPage::Free(TBufferPage* page) { +#if defined(PROFILE_MEMORY_ALLOCATIONS) + TotalBytesWastedCounter->Sub(page->Wasted()); +#endif free(page); } @@ -25,8 +38,8 @@ void TPagedBuffer::AppendPage() { TBufferPage* page = nullptr; if (Tail_) { auto tailPage = TBufferPage::GetPage(Tail_); - auto next = tailPage->Next(); - if (next) { + if (auto next = tailPage->Next()) { + // TODO: can we get here? page = next; page->Clear(); } else { @@ -54,6 +67,4 @@ TChunkedBuffer TPagedBuffer::AsChunkedBuffer(const TConstPtr& buffer) { return result; } -} // NMiniKQL - -} // NKikimr +} // namespace NKikimr::NMiniKQL diff --git a/yql/essentials/minikql/mkql_buffer.h b/yql/essentials/minikql/mkql_buffer.h index a1cf4d5aabb..97de3036c68 100644 --- a/yql/essentials/minikql/mkql_buffer.h +++ b/yql/essentials/minikql/mkql_buffer.h @@ -2,15 +2,22 @@ #include "defs.h" +#if defined(PROFILE_MEMORY_ALLOCATIONS) +# include <library/cpp/monlib/dynamic_counters/counters.h> +#endif + #include <yql/essentials/utils/chunked_buffer.h> #include <util/generic/noncopyable.h> #include <util/stream/output.h> #include <util/system/yassert.h> -namespace NKikimr { +namespace NKikimr::NMiniKQL { -namespace NMiniKQL { +#if defined(PROFILE_MEMORY_ALLOCATIONS) +extern NMonitoring::TDynamicCounters::TCounterPtr TotalBytesWastedCounter; +void InitializeGlobalPagedBufferCounters(::NMonitoring::TDynamicCounterPtr root); +#endif class TPagedBuffer; @@ -48,6 +55,10 @@ public: Size_ = 0; } + inline size_t Wasted() const { + return PageCapacity - Size_; + } + private: TBufferPage* Next_ = nullptr; size_t Size_ = 0; @@ -75,6 +86,9 @@ class TPagedBuffer : private TNonCopyable { ~TPagedBuffer() { if (Head_) { + auto* tailPage = TBufferPage::GetPage(Tail_); + tailPage->Size_ = TailSize_; + TBufferPage* curr = TBufferPage::GetPage(Head_); while (curr) { auto drop = curr; @@ -117,7 +131,6 @@ class TPagedBuffer : private TNonCopyable { } inline size_t Size() const { - // + (Tail_ ? TailSize_ : 0); size_t sizeWithReserve = ClosedPagesSize_ + ((-size_t(Tail_ != nullptr)) & TailSize_); Y_DEBUG_ABORT_UNLESS(sizeWithReserve >= HeadReserve_); return sizeWithReserve - HeadReserve_; @@ -171,26 +184,35 @@ class TPagedBuffer : private TNonCopyable { } inline void Clear() { + // TODO: not wasted or never called? Tail_ = Head_; ClosedPagesSize_ = HeadReserve_ = 0; - // = Tail_ ? 0 : TBufferPage::PageAllocSize; TailSize_ = (-size_t(Tail_ == nullptr)) & TBufferPage::PageCapacity; } inline void EraseBack(size_t len) { Y_DEBUG_ABORT_UNLESS(Tail_ && TailSize_ >= len); TailSize_ -= len; +#if defined(PROFILE_MEMORY_ALLOCATIONS) + TotalBytesWastedCounter->Add(len); +#endif } inline void Advance(size_t len) { if (Y_LIKELY(TailSize_ + len <= TBufferPage::PageCapacity)) { TailSize_ += len; +#if defined(PROFILE_MEMORY_ALLOCATIONS) + TotalBytesWastedCounter->Sub(len); +#endif return; } MKQL_ENSURE(len <= TBufferPage::PageCapacity, "Advance() size too big"); AppendPage(); TailSize_ = len; +#if defined(PROFILE_MEMORY_ALLOCATIONS) + TotalBytesWastedCounter->Sub(len); +#endif } inline void Append(char c) { @@ -211,6 +233,9 @@ class TPagedBuffer : private TNonCopyable { TailSize_ += chunk; data += chunk; size -= chunk; +#if defined(PROFILE_MEMORY_ALLOCATIONS) + TotalBytesWastedCounter->Sub(chunk); +#endif } } @@ -227,6 +252,4 @@ private: size_t ClosedPagesSize_ = 0; }; -} // NMiniKQL - -} // NKikimr +} // namespace NKikimr::NMiniKQL |