Skip to content

Commit 6134eec

Browse files
committed
Added per pool per class used size metrics
(cherry picked from commit ea5b3a3)
1 parent 7531144 commit 6134eec

File tree

11 files changed

+80
-1
lines changed

11 files changed

+80
-1
lines changed

cachelib/allocator/CacheAllocator-inl.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -287,6 +287,20 @@ CacheAllocator<CacheTrait>::allocate(PoolId poolId,
287287
ttlSecs == 0 ? 0 : creationTime + ttlSecs);
288288
}
289289

290+
template <typename CacheTrait>
291+
ClassId CacheAllocator<CacheTrait>::getAllocClassId(PoolId pid,
292+
typename Item::Key key,
293+
uint32_t size) const {
294+
const auto requiredSize = Item::getRequiredSize(key, size);
295+
return allocator_->getAllocationClassId(pid, requiredSize);
296+
}
297+
298+
template <typename CacheTrait>
299+
uint64_t CacheAllocator<CacheTrait>::getAllocationSize(ClassId cid,
300+
PoolId pid) const {
301+
return getPool(pid).getAllocationClass(cid).getAllocSize();
302+
}
303+
290304
template <typename CacheTrait>
291305
typename CacheAllocator<CacheTrait>::WriteHandle
292306
CacheAllocator<CacheTrait>::allocateInternal(PoolId pid,
@@ -324,6 +338,7 @@ CacheAllocator<CacheTrait>::allocateInternal(PoolId pid,
324338

325339
handle = acquire(new (memory) Item(key, size, creationTime, expiryTime));
326340
if (handle) {
341+
(*stats_.usedSize)[pid][cid].set(allocator_->getPoolUsedSize(pid));
327342
handle.markNascent();
328343
(*stats_.fragmentationSize)[pid][cid].add(
329344
util::getFragmentation(*this, *handle));
@@ -2239,7 +2254,7 @@ PoolStats CacheAllocator<CacheTrait>::getPoolStats(PoolId poolId) const {
22392254
(*stats_.fragmentationSize)[poolId][cid].get(), classHits,
22402255
(*stats_.chainedItemEvictions)[poolId][cid].get(),
22412256
(*stats_.regularItemEvictions)[poolId][cid].get(),
2242-
container.getStats()}});
2257+
(*stats_.usedSize)[poolId][cid].get(), container.getStats()}});
22432258
totalHits += classHits;
22442259
}
22452260
}

cachelib/allocator/CacheAllocator.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1110,6 +1110,12 @@ class CacheAllocator : public CacheBase {
11101110
// Whether this cache allocator was created on shared memory.
11111111
bool isOnShm() const noexcept { return isOnShm_; }
11121112

1113+
ClassId getAllocClassId(PoolId pid,
1114+
typename Item::Key key,
1115+
uint32_t size) const;
1116+
1117+
uint64_t getAllocationSize(ClassId cid, PoolId pid) const;
1118+
11131119
// Whether NvmCache is currently enabled
11141120
bool isNvmCacheEnabled() const noexcept {
11151121
return nvmCache_ && nvmCache_->isEnabled();

cachelib/allocator/CacheStats.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ void Stats::init() {
2929
allocFailures = std::make_unique<PerPoolClassAtomicCounters>();
3030
chainedItemEvictions = std::make_unique<PerPoolClassAtomicCounters>();
3131
regularItemEvictions = std::make_unique<PerPoolClassAtomicCounters>();
32+
usedSize = std::make_unique<PerPoolClassAtomicCounters>();
3233
auto initToZero = [](auto& a) {
3334
for (auto& s : a) {
3435
for (auto& c : s) {
@@ -42,6 +43,7 @@ void Stats::init() {
4243
initToZero(*fragmentationSize);
4344
initToZero(*chainedItemEvictions);
4445
initToZero(*regularItemEvictions);
46+
initToZero(*usedSize);
4547
}
4648

4749
template <int>
@@ -125,6 +127,14 @@ void Stats::populateGlobalCacheStats(GlobalCacheStats& ret) const {
125127
ret.numEvictions = accum(*chainedItemEvictions);
126128
ret.numEvictions += accum(*regularItemEvictions);
127129

130+
for (const auto& x : *usedSize) {
131+
uint64_t sum{0};
132+
for (const auto& v : x) {
133+
sum += v.get();
134+
}
135+
ret.poolUsedSize.emplace_back(sum);
136+
}
137+
128138
ret.invalidAllocs = invalidAllocs.get();
129139
ret.numRefcountOverflow = numRefcountOverflow.get();
130140

@@ -176,6 +186,7 @@ PoolStats& PoolStats::operator+=(const PoolStats& other) {
176186
d.numHits += s.numHits;
177187
d.chainedItemEvictions += s.chainedItemEvictions;
178188
d.regularItemEvictions += s.regularItemEvictions;
189+
d.usedSize += s.usedSize;
179190
}
180191

181192
// aggregate container stats within CacheStat

cachelib/allocator/CacheStats.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,9 @@ struct CacheStat {
121121
// number of regular items that were evicted from this classId
122122
uint64_t regularItemEvictions;
123123

124+
// used size of this classId
125+
uint64_t usedSize;
126+
124127
// the stats from the mm container
125128
MMContainerStat containerStat;
126129

@@ -416,6 +419,9 @@ struct GlobalCacheStats {
416419
// number of evictions across all the pools in the cache.
417420
uint64_t numEvictions{0};
418421

422+
// Used size of all the pools
423+
std::vector<uint64_t> poolUsedSize;
424+
419425
// number of allocation attempts with invalid input params.
420426
uint64_t invalidAllocs{0};
421427

cachelib/allocator/CacheStatsInternal.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ struct Stats {
220220
std::unique_ptr<PerPoolClassAtomicCounters> fragmentationSize{};
221221
std::unique_ptr<PerPoolClassAtomicCounters> chainedItemEvictions{};
222222
std::unique_ptr<PerPoolClassAtomicCounters> regularItemEvictions{};
223+
std::unique_ptr<PerPoolClassAtomicCounters> usedSize{};
223224

224225
// Eviction failures due to parent cannot be removed from access container
225226
AtomicCounter evictFailParentAC{0};

cachelib/allocator/memory/MemoryAllocator.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -633,6 +633,12 @@ class MemoryAllocator {
633633
memoryPoolManager_.updateNumSlabsToAdvise(numSlabs);
634634
}
635635

636+
// fetch used size of a particular pool
637+
// @return used size of the pool
638+
size_t getPoolUsedSize(PoolId id) {
639+
return slabAllocator_.getPoolUsedSize(id);
640+
}
641+
636642
private:
637643
// @param memory pointer to the memory.
638644
// @return the MemoryPool corresponding to the memory.

cachelib/allocator/memory/SlabAllocator.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,13 @@ SlabAllocator::~SlabAllocator() {
9191
}
9292
}
9393

94+
size_t SlabAllocator::getPoolUsedSize(PoolId id) {
95+
if (id >= memoryPoolSize_.size()) {
96+
throw std::invalid_argument(folly::sformat("Invalid pool id {}.", id));
97+
}
98+
return memoryPoolSize_[id];
99+
}
100+
94101
void SlabAllocator::stopMemoryLocker() {
95102
if (memoryLocker_.joinable()) {
96103
stopLocking_ = true;

cachelib/allocator/memory/SlabAllocator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,10 @@ class SlabAllocator {
316316
return PtrCompressor<PtrType, SlabAllocator>(*this);
317317
}
318318

319+
// Retrive used size of a pool
320+
// @return used size of Pool
321+
size_t getPoolUsedSize(PoolId id);
322+
319323
private:
320324
// null Slab* presenttation. With 4M Slab size, a valid slab index would never
321325
// reach 2^16 - 1;

cachelib/allocator/tests/AllocatorHitStatsTest.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include <mutex>
2626
#include <set>
2727
#include <thread>
28+
#include <unordered_map>
2829
#include <vector>
2930

3031
#include "cachelib/allocator/CacheAllocator.h"
@@ -247,17 +248,31 @@ class AllocatorHitStatsTest : public SlabAllocatorTestBase {
247248
std::vector<std::string> keys;
248249
const unsigned int nKeys = 1000;
249250
unsigned int initialAllocs = 0;
251+
std::unordered_map<ClassId, uint64_t> pool1Alloc;
250252
while (keys.size() != nKeys) {
251253
const auto keyLen = folly::Random::rand32(10, 100);
252254
const auto allocSize = folly::Random::rand32(100, 1024 * 1024 - 1000);
253255
auto str = cachelib::test_util::getRandomAsciiStr(keyLen);
254256
++initialAllocs;
257+
auto classId = alloc.getAllocClassId(poolId, str, allocSize);
255258
auto handle = util::allocateAccessible(alloc, poolId, str, allocSize);
256259
if (handle) {
257260
keys.push_back(str);
261+
pool1Alloc[classId] += alloc.getAllocationSize(classId, poolId);
258262
}
259263
}
260264

265+
// Adjust pool alloc size for each class to its ceiling slab size
266+
// and calculate the total
267+
uint64_t pool1AllocSize = 0;
268+
for (const auto& cAlloc : pool1Alloc) {
269+
pool1AllocSize += (cAlloc.second + Slab::kSize - 1) / Slab::kSize;
270+
}
271+
pool1AllocSize *= Slab::kSize;
272+
const auto tempCacheStats = alloc.getGlobalCacheStats();
273+
ASSERT_EQ(tempCacheStats.poolUsedSize.size(), MemoryPoolManager::kMaxPools);
274+
ASSERT_EQ(tempCacheStats.poolUsedSize[0], pool1AllocSize);
275+
261276
if (!evictedKeys.empty()) {
262277
for (const auto& key : evictedKeys) {
263278
auto it = std::find(keys.begin(), keys.end(), key);

cachelib/cachebench/cache/Cache-inl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -461,6 +461,7 @@ Stats Cache<Allocator>::getStats() const {
461461
ret.allocAttempts = cacheStats.allocAttempts;
462462
ret.allocFailures = cacheStats.allocFailures;
463463

464+
ret.poolUsedSize = cacheStats.poolUsedSize;
464465
ret.numCacheGets = cacheStats.numCacheGets;
465466
ret.numCacheGetMiss = cacheStats.numCacheGetMiss;
466467
ret.numRamDestructorCalls = cacheStats.numRamDestructorCalls;

0 commit comments

Comments
 (0)