Skip to content

Commit 6fa3770

Browse files
committed
added per tier pool class rolling average latency
1 parent 57a3d1c commit 6fa3770

File tree

7 files changed

+112
-1
lines changed

7 files changed

+112
-1
lines changed

cachelib/allocator/Cache.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ class CacheBase {
8484
CacheBase& operator=(CacheBase&&) = default;
8585

8686
// TODO: come up with some reasonable number
87-
static constexpr unsigned kMaxTiers = 8;
87+
static constexpr unsigned kMaxTiers = 2;
8888

8989
// Get a string referring to the cache name for this cache
9090
virtual const std::string getCacheName() const = 0;

cachelib/allocator/CacheAllocator-inl.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,6 +382,7 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
382382

383383
// the allocation class in our memory allocator.
384384
const auto cid = allocator_[tid]->getAllocationClassId(pid, requiredSize);
385+
util::RollingLatencyTracker rollTracker{(*stats_.classAllocLatency)[tid][pid][cid]};
385386

386387
// TODO: per-tier
387388
(*stats_.allocAttempts)[pid][cid].inc();
@@ -480,6 +481,8 @@ CacheAllocator<CacheTrait>::allocateChainedItemInternal(
480481
const auto pid = allocator_[tid]->getAllocInfo(parent->getMemory()).poolId;
481482
const auto cid = allocator_[tid]->getAllocationClassId(pid, requiredSize);
482483

484+
util::RollingLatencyTracker rollTracker{(*stats_.classAllocLatency)[tid][pid][cid]};
485+
483486
// TODO: per-tier? Right now stats_ are not used in any public periodic
484487
// worker
485488
(*stats_.allocAttempts)[pid][cid].inc();
@@ -2540,6 +2543,7 @@ AllocationClassBaseStat CacheAllocator<CacheTrait>::getAllocationClassStats(
25402543
} else {
25412544
stats.approxFreePercent = ac.approxFreePercentage();
25422545
}
2546+
stats.allocLatencyNs = (*stats_.classAllocLatency)[tid][pid][cid];
25432547

25442548
return stats;
25452549
}

cachelib/allocator/CacheStats.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ void Stats::init() {
4242
initToZero(*fragmentationSize);
4343
initToZero(*chainedItemEvictions);
4444
initToZero(*regularItemEvictions);
45+
46+
classAllocLatency = std::make_unique<PerTierPoolClassRollingStats>();
4547
}
4648

4749
template <int>

cachelib/allocator/CacheStats.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "cachelib/allocator/memory/Slab.h"
2626
#include "cachelib/common/FastStats.h"
2727
#include "cachelib/common/PercentileStats.h"
28+
#include "cachelib/common/RollingStats.h"
2829
#include "cachelib/common/Time.h"
2930

3031
namespace facebook {
@@ -107,6 +108,9 @@ struct AllocationClassBaseStat {
107108

108109
// percent of free memory in this class
109110
double approxFreePercent{0.0};
111+
112+
// Rolling allocation latency (in ns)
113+
util::RollingStats allocLatencyNs;
110114
};
111115

112116
// cache related stats for a given allocation class.

cachelib/allocator/CacheStatsInternal.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
#include "cachelib/allocator/Cache.h"
2222
#include "cachelib/allocator/memory/MemoryAllocator.h"
2323
#include "cachelib/common/AtomicCounter.h"
24+
#include "cachelib/common/RollingStats.h"
2425

2526
namespace facebook {
2627
namespace cachelib {
@@ -221,6 +222,15 @@ struct Stats {
221222
std::unique_ptr<PerPoolClassAtomicCounters> chainedItemEvictions{};
222223
std::unique_ptr<PerPoolClassAtomicCounters> regularItemEvictions{};
223224

225+
using PerTierPoolClassRollingStats =
226+
std::array<std::array<std::array<util::RollingStats,
227+
MemoryAllocator::kMaxClasses>,
228+
MemoryPoolManager::kMaxPools>,
229+
CacheBase::kMaxTiers>;
230+
231+
// rolling latency tracking for every alloc class in every pool
232+
std::unique_ptr<PerTierPoolClassRollingStats> classAllocLatency{};
233+
224234
// Eviction failures due to parent cannot be removed from access container
225235
AtomicCounter evictFailParentAC{0};
226236

cachelib/cachebench/cache/CacheStats.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,12 @@ struct Stats {
163163
out << folly::sformat("tid{:2} pid{:2} cid{:4} {:8.2f}{} free: {:4.2f}%",
164164
tid, pid, cid, allocSize, allocSizeSuffix, stats.approxFreePercent) << std::endl;
165165
});
166+
167+
foreachAC([&](auto tid, auto pid, auto cid, auto stats){
168+
auto [allocSizeSuffix, allocSize] = formatMemory(stats.allocSize);
169+
out << folly::sformat("tid{:2} pid{:2} cid{:4} {:8.2f}{} latency: {:8.2f}%",
170+
tid, pid, cid, allocSize, allocSizeSuffix, stats.allocLatencyNs.estimate()) << std::endl;
171+
});
166172
}
167173

168174
if (numCacheGets > 0) {

cachelib/common/RollingStats.h

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. and its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include <folly/Range.h>
20+
#include <folly/logging/xlog.h>
21+
22+
#include "cachelib/common/Utils.h"
23+
24+
namespace facebook {
25+
namespace cachelib {
26+
namespace util {
27+
28+
class RollingStats {
29+
public:
30+
// track latency by taking the value of duration directly.
31+
void trackValue(double value) {
32+
auto ratio = static_cast<double>(cnt_) / (cnt_ + 1);
33+
avg_ *= ratio;
34+
++cnt_;
35+
avg_ += value / cnt_;
36+
}
37+
38+
// Return the rolling average.
39+
uint64_t estimate() {
40+
return static_cast<uint64_t>(avg_);
41+
}
42+
43+
private:
44+
double avg_ = 0;
45+
uint64_t cnt_ = 0;
46+
};
47+
48+
class RollingLatencyTracker {
49+
public:
50+
explicit RollingLatencyTracker(RollingStats& stats)
51+
: stats_(&stats), begin_(std::chrono::steady_clock::now()) {}
52+
RollingLatencyTracker() {}
53+
~RollingLatencyTracker() {
54+
if (stats_) {
55+
auto tp = std::chrono::steady_clock::now();
56+
auto diffNanos =
57+
std::chrono::duration_cast<std::chrono::nanoseconds>(tp - begin_)
58+
.count();
59+
stats_->trackValue(static_cast<double>(diffNanos));
60+
}
61+
}
62+
63+
RollingLatencyTracker(const RollingLatencyTracker&) = delete;
64+
RollingLatencyTracker& operator=(const RollingLatencyTracker&) = delete;
65+
66+
RollingLatencyTracker(RollingLatencyTracker&& rhs) noexcept
67+
: stats_(rhs.stats_), begin_(rhs.begin_) {
68+
rhs.stats_ = nullptr;
69+
}
70+
71+
RollingLatencyTracker& operator=(RollingLatencyTracker&& rhs) noexcept {
72+
if (this != &rhs) {
73+
this->~RollingLatencyTracker();
74+
new (this) RollingLatencyTracker(std::move(rhs));
75+
}
76+
return *this;
77+
}
78+
79+
private:
80+
RollingStats* stats_{nullptr};
81+
std::chrono::time_point<std::chrono::steady_clock> begin_;
82+
};
83+
} // namespace util
84+
} // namespace cachelib
85+
} // namespace facebook

0 commit comments

Comments
 (0)