Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions cachelib/allocator/CacheAllocator-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -303,6 +303,20 @@ CacheAllocator<CacheTrait>::allocate(PoolId poolId,
ttlSecs == 0 ? 0 : creationTime + ttlSecs);
}

template <typename CacheTrait>
ClassId CacheAllocator<CacheTrait>::getAllocClassId(PoolId pid,
typename Item::Key key,
uint32_t size) const {
const auto requiredSize = Item::getRequiredSize(key, size);
return allocator_->getAllocationClassId(pid, requiredSize);
}

template <typename CacheTrait>
uint64_t CacheAllocator<CacheTrait>::getAllocationSize(ClassId cid,
PoolId pid) const {
return getPool(pid).getAllocationClass(cid).getAllocSize();
}

template <typename CacheTrait>
typename CacheAllocator<CacheTrait>::WriteHandle
CacheAllocator<CacheTrait>::allocateInternal(PoolId pid,
Expand Down Expand Up @@ -340,6 +354,7 @@ CacheAllocator<CacheTrait>::allocateInternal(PoolId pid,

handle = acquire(new (memory) Item(key, size, creationTime, expiryTime));
if (handle) {
stats_.usedSize_[pid].set(allocator_->getPoolUsedSize(pid));
handle.markNascent();
(*stats_.fragmentationSize)[pid][cid].add(
util::getFragmentation(*this, *handle));
Expand Down
6 changes: 6 additions & 0 deletions cachelib/allocator/CacheAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -1116,6 +1116,12 @@ class CacheAllocator : public CacheBase {
// Whether this cache allocator was created on shared memory.
bool isOnShm() const noexcept { return isOnShm_; }

ClassId getAllocClassId(PoolId pid,
typename Item::Key key,
uint32_t size) const;

uint64_t getAllocationSize(ClassId cid, PoolId pid) const;

// Whether NvmCache is currently enabled
bool isNvmCacheEnabled() const noexcept {
return nvmCache_ && nvmCache_->isEnabled();
Expand Down
6 changes: 5 additions & 1 deletion cachelib/allocator/CacheStats.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ struct SizeVerify {};

void Stats::populateGlobalCacheStats(GlobalCacheStats& ret) const {
#ifndef SKIP_SIZE_VERIFY
SizeVerify<sizeof(Stats)> a = SizeVerify<16160>{};
SizeVerify<sizeof(Stats)> a = SizeVerify<16672>{};
std::ignore = a;
#endif
ret.numCacheGets = numCacheGets.get();
Expand Down Expand Up @@ -125,6 +125,10 @@ void Stats::populateGlobalCacheStats(GlobalCacheStats& ret) const {
ret.numEvictions = accum(*chainedItemEvictions);
ret.numEvictions += accum(*regularItemEvictions);

for (const auto& x : usedSize_) {
ret.poolUsedSize.emplace_back(x.get());
}

ret.invalidAllocs = invalidAllocs.get();
ret.numRefcountOverflow = numRefcountOverflow.get();

Expand Down
3 changes: 3 additions & 0 deletions cachelib/allocator/CacheStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -416,6 +416,9 @@ struct GlobalCacheStats {
// number of evictions across all the pools in the cache.
uint64_t numEvictions{0};

// Used size of all the pools
std::vector<uint64_t> poolUsedSize;

// number of allocation attempts with invalid input params.
uint64_t invalidAllocs{0};

Expand Down
2 changes: 2 additions & 0 deletions cachelib/allocator/CacheStatsInternal.h
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,8 @@ struct Stats {
std::unique_ptr<PerPoolClassAtomicCounters> chainedItemEvictions{};
std::unique_ptr<PerPoolClassAtomicCounters> regularItemEvictions{};

std::array<AtomicCounter, MemoryPoolManager::kMaxPools> usedSize_;

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

Expand Down
6 changes: 6 additions & 0 deletions cachelib/allocator/memory/MemoryAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -644,6 +644,12 @@ class MemoryAllocator {
memoryPoolManager_.updateNumSlabsToAdvise(numSlabs);
}

// fetch used size of a particular pool
// @return used size of the pool
size_t getPoolUsedSize(PoolId id) {
return slabAllocator_.getPoolUsedSize(id);
}

private:
// @param memory pointer to the memory.
// @return the MemoryPool corresponding to the memory.
Expand Down
7 changes: 7 additions & 0 deletions cachelib/allocator/memory/SlabAllocator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,13 @@ SlabAllocator::~SlabAllocator() {
}
}

size_t SlabAllocator::getPoolUsedSize(PoolId id) {
if (id >= memoryPoolSize_.size()) {
throw std::invalid_argument(folly::sformat("Invalid pool id {}.", id));
}
return memoryPoolSize_[id];
}

void SlabAllocator::stopMemoryLocker() {
if (memoryLocker_.joinable()) {
stopLocking_ = true;
Expand Down
4 changes: 4 additions & 0 deletions cachelib/allocator/memory/SlabAllocator.h
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,10 @@ class SlabAllocator {
return PtrCompressor<PtrType, SlabAllocator>(*this);
}

// Retrive used size of a pool
// @return used size of Pool
size_t getPoolUsedSize(PoolId id);

private:
// null Slab* presenttation. With 4M Slab size, a valid slab index would never
// reach 2^16 - 1;
Expand Down
23 changes: 22 additions & 1 deletion cachelib/allocator/tests/AllocatorHitStatsTest.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include <mutex>
#include <set>
#include <thread>
#include <unordered_map>
#include <vector>

#include "cachelib/allocator/CacheAllocator.h"
Expand Down Expand Up @@ -246,15 +247,35 @@ class AllocatorHitStatsTest : public SlabAllocatorTestBase {
// allocations across a set of sizes.
std::vector<std::string> keys;
const unsigned int nKeys = 1000;
unsigned int initialAllocs = 0;
const unsigned int nChkPoint = 20;
unsigned int initialAllocs = 0, successAllocs = 0;
std::unordered_map<ClassId, uint64_t> pool1Alloc;
while (keys.size() != nKeys) {
const auto keyLen = folly::Random::rand32(10, 100);
const auto allocSize = folly::Random::rand32(100, 1024 * 1024 - 1000);
auto str = cachelib::test_util::getRandomAsciiStr(keyLen);
++initialAllocs;
auto classId = alloc.getAllocClassId(poolId, str, allocSize);
auto handle = util::allocateAccessible(alloc, poolId, str, allocSize);
if (handle) {
keys.push_back(str);
pool1Alloc[classId] += alloc.getAllocationSize(classId, poolId);
if (++successAllocs == nChkPoint) {
// This check helps to verify accuracy of pool used size before
// evictions start to occur. Adjust pool alloc size for each class
// to its ceiling slab size and calculate the total. This should
// match the pool used size reported by global stats counter.
uint64_t pool1AllocSize = 0;
for (const auto& cAlloc : pool1Alloc) {
pool1AllocSize += (cAlloc.second + Slab::kSize - 1) / Slab::kSize;
}
pool1AllocSize *= Slab::kSize;
const auto tempCacheStats = alloc.getGlobalCacheStats();
ASSERT_EQ(tempCacheStats.numEvictions, 0);
ASSERT_EQ(tempCacheStats.poolUsedSize.size(),
MemoryPoolManager::kMaxPools);
ASSERT_EQ(tempCacheStats.poolUsedSize[0], pool1AllocSize);
}
}
}

Expand Down
1 change: 1 addition & 0 deletions cachelib/cachebench/cache/Cache-inl.h
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,7 @@ Stats Cache<Allocator>::getStats() const {
ret.allocAttempts = cacheStats.allocAttempts;
ret.allocFailures = cacheStats.allocFailures;

ret.poolUsedSize = cacheStats.poolUsedSize;
ret.numCacheGets = cacheStats.numCacheGets;
ret.numCacheGetMiss = cacheStats.numCacheGetMiss;
ret.numRamDestructorCalls = cacheStats.numRamDestructorCalls;
Expand Down
7 changes: 7 additions & 0 deletions cachelib/cachebench/cache/CacheStats.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ struct Stats {
uint64_t allocAttempts{0};
uint64_t allocFailures{0};

std::vector<uint64_t> poolUsedSize;
uint64_t numCacheGets{0};
uint64_t numCacheGetMiss{0};
uint64_t numRamDestructorCalls{0};
Expand Down Expand Up @@ -116,6 +117,12 @@ struct Stats {
<< std::endl;
out << folly::sformat("RAM Evictions : {:,}", numEvictions) << std::endl;

for (auto pid = 0U; pid < poolUsedSize.size(); pid++) {
out << folly::sformat("Pool {:,} Used size : {:,} Bytes", pid,
poolUsedSize[pid])
<< std::endl;
}

if (numCacheGets > 0) {
out << folly::sformat("Cache Gets : {:,}", numCacheGets) << std::endl;
out << folly::sformat("Hit Ratio : {:6.2f}%", overallHitRatio)
Expand Down