diff options
author | va-kuznecov <va-kuznecov@ydb.tech> | 2023-08-07 17:37:26 +0300 |
---|---|---|
committer | va-kuznecov <va-kuznecov@ydb.tech> | 2023-08-07 20:32:28 +0300 |
commit | 3d7db4ecff29d4855e220be26cd2d993ff7328e0 (patch) | |
tree | 78fe1d10fc333092c902ceaafb4b967c0b74e5d3 /library/cpp | |
parent | b76e3a18a545bb224d408a16c5e52289cdffbe02 (diff) | |
download | ydb-3d7db4ecff29d4855e220be26cd2d993ff7328e0.tar.gz |
Use relaxed memory order in TPercentileTracker[Lg] KIKIMR-18953
Diffstat (limited to 'library/cpp')
3 files changed, 46 insertions, 26 deletions
diff --git a/library/cpp/monlib/dynamic_counters/percentile/percentile.h b/library/cpp/monlib/dynamic_counters/percentile/percentile.h index 73c482bce9..db40793adf 100644 --- a/library/cpp/monlib/dynamic_counters/percentile/percentile.h +++ b/library/cpp/monlib/dynamic_counters/percentile/percentile.h @@ -10,15 +10,15 @@ namespace NMonitoring { template <size_t BUCKET_SIZE, size_t BUCKET_COUNT, size_t FRAME_COUNT> struct TPercentileTracker : public TPercentileBase { - TAtomic Items[BUCKET_COUNT]; - TAtomicBase Frame[FRAME_COUNT][BUCKET_COUNT]; + std::atomic<size_t> Items[BUCKET_COUNT]; + size_t Frame[FRAME_COUNT][BUCKET_COUNT]; size_t CurrentFrame; TPercentileTracker() : CurrentFrame(0) { for (size_t i = 0; i < BUCKET_COUNT; ++i) { - AtomicSet(Items[i], 0); + Items[i].store(0); } for (size_t frame = 0; frame < FRAME_COUNT; ++frame) { for (size_t bucket = 0; bucket < BUCKET_COUNT; ++bucket) { @@ -28,17 +28,18 @@ struct TPercentileTracker : public TPercentileBase { } void Increment(size_t value) { - AtomicIncrement(Items[Min((value + BUCKET_SIZE - 1) / BUCKET_SIZE, BUCKET_COUNT - 1)]); + auto idx = Min((value + BUCKET_SIZE - 1) / BUCKET_SIZE, BUCKET_COUNT - 1); + Items[idx].fetch_add(1, std::memory_order_relaxed); } // shift frame (call periodically) void Update() { - TVector<TAtomicBase> totals(BUCKET_COUNT); + TVector<size_t> totals(BUCKET_COUNT); totals.resize(BUCKET_COUNT); - TAtomicBase total = 0; + size_t total = 0; for (size_t i = 0; i < BUCKET_COUNT; ++i) { - TAtomicBase item = AtomicGet(Items[i]); - TAtomicBase prevItem = Frame[CurrentFrame][i]; + size_t item = Items[i].load(std::memory_order_relaxed); + size_t prevItem = Frame[CurrentFrame][i]; Frame[CurrentFrame][i] = item; total += item - prevItem; totals[i] = total; @@ -46,7 +47,7 @@ struct TPercentileTracker : public TPercentileBase { for (size_t i = 0; i < Percentiles.size(); ++i) { TPercentile &percentile = Percentiles[i]; - auto threshold = (TAtomicBase)(percentile.first * (float)total); + auto threshold = (size_t)(percentile.first * (float)total); threshold = Min(threshold, total); auto it = LowerBound(totals.begin(), totals.end(), threshold); size_t index = it - totals.begin(); diff --git a/library/cpp/monlib/dynamic_counters/percentile/percentile_lg.h b/library/cpp/monlib/dynamic_counters/percentile/percentile_lg.h index 0042cd9a6a..e27664ded9 100644 --- a/library/cpp/monlib/dynamic_counters/percentile/percentile_lg.h +++ b/library/cpp/monlib/dynamic_counters/percentile/percentile_lg.h @@ -24,8 +24,8 @@ struct TPercentileTrackerLg : public TPercentileBase { static constexpr size_t MAX_GRANULARITY = size_t(1) << (BUCKET_COUNT - 1); size_t Borders[BUCKET_COUNT]; - TAtomic Items[ITEMS_COUNT]; - TAtomicBase Frame[FRAME_COUNT][ITEMS_COUNT]; + std::atomic<size_t> Items[ITEMS_COUNT]; + size_t Frame[FRAME_COUNT][ITEMS_COUNT]; size_t CurrentFrame; TPercentileTrackerLg() @@ -36,7 +36,7 @@ struct TPercentileTrackerLg : public TPercentileBase { Borders[i] = Borders[i-1] + (BUCKET_SIZE << (i - 1)); } for (size_t i = 0; i < ITEMS_COUNT; ++i) { - AtomicSet(Items[i], 0); + Items[i].store(0); } for (size_t frame = 0; frame < FRAME_COUNT; ++frame) { for (size_t bucket = 0; bucket < ITEMS_COUNT; ++bucket) { @@ -135,18 +135,18 @@ struct TPercentileTrackerLg : public TPercentileBase { size_t bucket_idx = BucketIdxMostSignificantBit(value); size_t inside_bucket_idx = (value - Borders[bucket_idx] + (1 << bucket_idx) - 1) >> bucket_idx; size_t idx = bucket_idx * BUCKET_SIZE + inside_bucket_idx; - AtomicIncrement(Items[Min(idx, ITEMS_COUNT - 1)]); + Items[Min(idx, ITEMS_COUNT - 1)].fetch_add(1, std::memory_order_relaxed); } // Needed only for tests size_t GetPercentile(float threshold) { - TStackVec<TAtomicBase, ITEMS_COUNT> totals(ITEMS_COUNT); - TAtomicBase total = 0; + TStackVec<size_t, ITEMS_COUNT> totals(ITEMS_COUNT); + size_t total = 0; for (size_t i = 0; i < ITEMS_COUNT; ++i) { - total += AtomicGet(Items[i]); + total += Items[i].load(); totals[i] = total; } - TAtomicBase item_threshold = std::llround(threshold * (float)total); + size_t item_threshold = std::llround(threshold * (float)total); item_threshold = Min(item_threshold, total); auto it = LowerBound(totals.begin(), totals.end(), item_threshold); size_t index = it - totals.begin(); @@ -156,11 +156,11 @@ struct TPercentileTrackerLg : public TPercentileBase { // shift frame (call periodically) void Update() { - TStackVec<TAtomicBase, ITEMS_COUNT> totals(ITEMS_COUNT); - TAtomicBase total = 0; + TStackVec<size_t, ITEMS_COUNT> totals(ITEMS_COUNT); + size_t total = 0; for (size_t i = 0; i < ITEMS_COUNT; ++i) { - TAtomicBase item = AtomicGet(Items[i]); - TAtomicBase prevItem = Frame[CurrentFrame][i]; + size_t item = Items[i].load(std::memory_order_relaxed); + size_t prevItem = Frame[CurrentFrame][i]; Frame[CurrentFrame][i] = item; total += item - prevItem; totals[i] = total; @@ -168,7 +168,7 @@ struct TPercentileTrackerLg : public TPercentileBase { for (size_t i = 0; i < Percentiles.size(); ++i) { TPercentile &percentile = Percentiles[i]; - TAtomicBase threshold = std::llround(percentile.first * (float)total); + size_t threshold = std::llround(percentile.first * (float)total); threshold = Min(threshold, total); auto it = LowerBound(totals.begin(), totals.end(), threshold); size_t index = it - totals.begin(); diff --git a/library/cpp/monlib/dynamic_counters/percentile/percentile_ut.cpp b/library/cpp/monlib/dynamic_counters/percentile/percentile_ut.cpp index 6c8bb54ec9..b8bdd41028 100644 --- a/library/cpp/monlib/dynamic_counters/percentile/percentile_ut.cpp +++ b/library/cpp/monlib/dynamic_counters/percentile/percentile_ut.cpp @@ -1,27 +1,46 @@ +#include "percentile.h" #include "percentile_lg.h" #include <library/cpp/testing/unittest/registar.h> +#include <util/datetime/cputimer.h> using namespace NMonitoring; Y_UNIT_TEST_SUITE(PercentileTest) { template<size_t A, size_t B, size_t B_BEGIN> -void printSizeAndLimit() { +void PrintSizeAndLimit() { using TPerc = TPercentileTrackerLg<A, B, 15>; Cout << "TPercentileTrackerLg<" << A << ", " << B << ", 15>" << "; sizeof# " << LeftPad(HumanReadableSize(sizeof(TPerc), SF_BYTES), 7) << "; max_granularity# " << LeftPad(HumanReadableSize(TPerc::MAX_GRANULARITY, SF_QUANTITY), 5) << "; limit# " << LeftPad(HumanReadableSize(TPerc::TRACKER_LIMIT , SF_QUANTITY), 5) << Endl; if constexpr (B > 1) { - printSizeAndLimit<A, B - 1, B_BEGIN>(); + PrintSizeAndLimit<A, B - 1, B_BEGIN>(); } else if constexpr (A > 1) { Cout << Endl; - printSizeAndLimit<A - 1, B_BEGIN, B_BEGIN>(); + PrintSizeAndLimit<A - 1, B_BEGIN, B_BEGIN>(); } } Y_UNIT_TEST(PrintTrackerLgSizeAndLimits) { - printSizeAndLimit<10, 5, 5>(); + PrintSizeAndLimit<10, 5, 5>(); + } + +template<class T> +void RunPerf() { + TTimer t(TypeName<T>() + "\n"); + T tracker; + for (size_t i = 0; i < 1000000; ++i) { + for (size_t i = 0; i < 10; ++i) { + tracker.Increment(i * 6451); + } + tracker.Update(); + } +} + + Y_UNIT_TEST(TrackerPerf) { + RunPerf<TPercentileTracker<4, 512, 15>>(); + RunPerf<TPercentileTrackerLg<4, 3, 15>>(); } Y_UNIT_TEST(TrackerLimitTest) { |