diff --git a/cachelib/allocator/BackgroundEvictor-inl.h b/cachelib/allocator/BackgroundEvictor-inl.h index 3221a45f32..55e09e2908 100644 --- a/cachelib/allocator/BackgroundEvictor-inl.h +++ b/cachelib/allocator/BackgroundEvictor-inl.h @@ -103,7 +103,7 @@ BackgroundEvictionStats BackgroundEvictor::getStats() const noexcept { evicStats.runCount = stats.numTraversals.get(); evicStats.evictionSize = stats.evictionSize.get(); evicStats.totalClasses = stats.totalClasses.get(); - + evicStats.strategyStats = strategy_->getStats(); return evicStats; } diff --git a/cachelib/allocator/BackgroundEvictor.h b/cachelib/allocator/BackgroundEvictor.h index 3b2886a3ae..0205ccb646 100644 --- a/cachelib/allocator/BackgroundEvictor.h +++ b/cachelib/allocator/BackgroundEvictor.h @@ -51,6 +51,7 @@ struct BackgroundEvictorStats { // item eviction size AtomicCounter evictionSize{0}; + }; // Periodic worker that evicts items from tiers in batches diff --git a/cachelib/allocator/BackgroundEvictorStrategy.h b/cachelib/allocator/BackgroundEvictorStrategy.h index 1d05a801bb..784cc53f82 100644 --- a/cachelib/allocator/BackgroundEvictorStrategy.h +++ b/cachelib/allocator/BackgroundEvictorStrategy.h @@ -27,6 +27,7 @@ class BackgroundEvictorStrategy { public: virtual std::vector calculateBatchSizes(const CacheBase& cache, std::vector> acVec) = 0; + virtual BackgroundStrategyStats getStats() = 0; }; } // namespace cachelib diff --git a/cachelib/allocator/CacheStats.h b/cachelib/allocator/CacheStats.h index c8af1a2a98..9e1ce79198 100644 --- a/cachelib/allocator/CacheStats.h +++ b/cachelib/allocator/CacheStats.h @@ -28,6 +28,8 @@ #include "cachelib/common/RollingStats.h" #include "cachelib/common/Time.h" +//#include "cachelib/allocator/BackgroundEvictorStrategy.h" + namespace facebook { namespace cachelib { @@ -300,6 +302,21 @@ struct ReaperStats { uint64_t avgTraversalTimeMs{0}; }; +struct BackgroundStrategyStats { + + std::map highEvictionAcWatermarks; + + BackgroundStrategyStats& operator+=(const BackgroundStrategyStats& rhs){ + for (const auto entry : rhs.highEvictionAcWatermarks) { + auto cid = entry.first; + auto count = entry.second; + highEvictionAcWatermarks[cid] = count; + } + return *this; + } + +}; + // Eviction Stats struct BackgroundEvictionStats { // the number of items this worker evicted by looking at pools/classes stats @@ -314,11 +331,14 @@ struct BackgroundEvictionStats { // eviction size uint64_t evictionSize{0}; + BackgroundStrategyStats strategyStats; + BackgroundEvictionStats& operator+=(const BackgroundEvictionStats& rhs) { numEvictedItems += rhs.numEvictedItems; runCount += rhs.runCount; totalClasses += rhs.totalClasses; evictionSize += rhs.evictionSize; + strategyStats += rhs.strategyStats; return *this; } }; diff --git a/cachelib/allocator/DynamicFreeThresholdStrategy.cpp b/cachelib/allocator/DynamicFreeThresholdStrategy.cpp index 1dd53b86f5..7d33aa9350 100644 --- a/cachelib/allocator/DynamicFreeThresholdStrategy.cpp +++ b/cachelib/allocator/DynamicFreeThresholdStrategy.cpp @@ -148,5 +148,19 @@ void DynamicFreeThresholdStrategy::calculateBenefitMig(uint64_t acLatency, unsig std::get<0>(acBenefits[tid][pid][cid]) = 1 / acLatency; } +BackgroundStrategyStats DynamicFreeThresholdStrategy::getStats() { + BackgroundStrategyStats s; + + auto numClasses = MemoryAllocator::kMaxClasses; + for (int i = 0; i < 1; i++) { + for (int j = 0; j < 1; j++) { + for (int k = 0; k < numClasses; k++) { + s.highEvictionAcWatermarks[k] = std::get<0>( highEvictionAcWatermarks[i][j][k] ); + } + } + } + return s; +} + } // namespace cachelib } // namespace facebook diff --git a/cachelib/allocator/DynamicFreeThresholdStrategy.h b/cachelib/allocator/DynamicFreeThresholdStrategy.h index 14fc08b370..44ef25da2c 100644 --- a/cachelib/allocator/DynamicFreeThresholdStrategy.h +++ b/cachelib/allocator/DynamicFreeThresholdStrategy.h @@ -38,11 +38,8 @@ class DynamicFreeThresholdStrategy : public BackgroundEvictorStrategy { ~DynamicFreeThresholdStrategy() {} std::vector calculateBatchSizes(const CacheBase& cache, std::vector> acVec); - //unsigned int tid, - //PoolId pid, - //ClassId cid, - //size_t allocSize, - //size_t acMemorySize); + + BackgroundStrategyStats getStats(); private: double lowEvictionAcWatermark{2.0}; //this threshold is used outside this class and is not adjusted currently diff --git a/cachelib/allocator/FreeThresholdStrategy.cpp b/cachelib/allocator/FreeThresholdStrategy.cpp index 5ffc718fa7..c34fa11218 100644 --- a/cachelib/allocator/FreeThresholdStrategy.cpp +++ b/cachelib/allocator/FreeThresholdStrategy.cpp @@ -63,5 +63,10 @@ std::vector FreeThresholdStrategy::calculateBatchSizes( return batches; } +BackgroundStrategyStats FreeThresholdStrategy::getStats() { + BackgroundStrategyStats s; + return s; +} + } // namespace cachelib } // namespace facebook diff --git a/cachelib/allocator/FreeThresholdStrategy.h b/cachelib/allocator/FreeThresholdStrategy.h index 6a6b0c8950..e4effea9d9 100644 --- a/cachelib/allocator/FreeThresholdStrategy.h +++ b/cachelib/allocator/FreeThresholdStrategy.h @@ -32,6 +32,8 @@ class FreeThresholdStrategy : public BackgroundEvictorStrategy { std::vector calculateBatchSizes(const CacheBase& cache, std::vector> acVecs); + + BackgroundStrategyStats getStats(); private: double lowEvictionAcWatermark{2.0}; double highEvictionAcWatermark{5.0}; diff --git a/cachelib/allocator/PromotionStrategy.h b/cachelib/allocator/PromotionStrategy.h index 8479c54dc1..4a42d5e663 100644 --- a/cachelib/allocator/PromotionStrategy.h +++ b/cachelib/allocator/PromotionStrategy.h @@ -71,6 +71,11 @@ class PromotionStrategy : public BackgroundEvictorStrategy { return batches; } + + BackgroundStrategyStats getStats() { + BackgroundStrategyStats s; + return s; + } private: double promotionAcWatermark{4.0}; uint64_t maxPromotionBatch{40}; diff --git a/cachelib/cachebench/cache/Cache-inl.h b/cachelib/cachebench/cache/Cache-inl.h index 0f555cc0d5..e8ab0ee680 100644 --- a/cachelib/cachebench/cache/Cache-inl.h +++ b/cachelib/cachebench/cache/Cache-inl.h @@ -614,6 +614,7 @@ Stats Cache::getStats() const { ret.nvmCounters = cache_->getNvmCacheStatsMap(); } + ret.acHighWatermarks = cacheStats.evictionStats.strategyStats.highEvictionAcWatermarks; ret.backgroundEvictionClasses = cache_->getBackgroundEvictorClassStats(); ret.backgroundPromotionClasses = cache_->getBackgroundPromoterClassStats(); diff --git a/cachelib/cachebench/cache/CacheStats.h b/cachelib/cachebench/cache/CacheStats.h index d2af5f0e5d..8595320399 100644 --- a/cachelib/cachebench/cache/CacheStats.h +++ b/cachelib/cachebench/cache/CacheStats.h @@ -135,6 +135,8 @@ struct Stats { std::map backgroundEvictionClasses; std::map backgroundPromotionClasses; + std::map acHighWatermarks; + // errors from the nvm engine. std::unordered_map nvmErrors; @@ -190,13 +192,13 @@ struct Stats { foreachAC([&](auto tid, auto pid, auto cid, auto stats){ auto [allocSizeSuffix, allocSize] = formatMemory(stats.allocSize); - out << folly::sformat("tid{:2} pid{:2} cid{:4} {:8.2f}{} free: {:4.2f}%", + out << folly::sformat("tid{:2} pid{:2} cid{:4} {:8}{} free: {:4.2f}%", tid, pid, cid, allocSize, allocSizeSuffix, stats.approxFreePercent) << std::endl; }); foreachAC([&](auto tid, auto pid, auto cid, auto stats){ auto [allocSizeSuffix, allocSize] = formatMemory(stats.allocSize); - out << folly::sformat("tid{:2} pid{:2} cid{:4} {:8.2f}{} latency: {:8.2f}%", + out << folly::sformat("tid{:2} pid{:2} cid{:4} {:8}{} latency: {:8}", tid, pid, cid, allocSize, allocSizeSuffix, stats.allocLatencyNs.estimate()) << std::endl; }); } @@ -380,6 +382,13 @@ struct Stats { } } + if (!acHighWatermarks.empty() && backgndEvicStats.nEvictedItems > 0 ) { + out << "== Class High Threshold ==" << std::endl; + for (const auto& it : acHighWatermarks) { + out << it.first << " : " << it.second << std::endl; + } + } + if (!backgroundPromotionClasses.empty() && backgndPromoStats.nPromotedItems > 0) { out << "== Class Background Promotion Counters Map ==" << std::endl; for (const auto& it : backgroundPromotionClasses) {