summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorilezhankin <[email protected]>2025-05-20 12:34:52 +0300
committerilezhankin <[email protected]>2025-05-20 12:48:53 +0300
commitde92acc01b681316ac8231ed3f31bf4d85b2a05c (patch)
tree744022cb4194678d0ed223b78f545956f3e46a86
parent21395e193baf5e561d5f33257a71fdd13a56f0f5 (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.cpp25
-rw-r--r--yql/essentials/minikql/mkql_buffer.h37
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