@@ -408,9 +408,8 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
408
408
util::RollingLatencyTracker rollTracker{
409
409
(*stats_.classAllocLatency )[tid][pid][cid]};
410
410
411
- // TODO: per-tier
412
- (*stats_.allocAttempts )[pid][cid].inc ();
413
-
411
+ (*stats_.allocAttempts )[tid][pid][cid].inc ();
412
+
414
413
void * memory = allocator_[tid]->allocate (pid, requiredSize);
415
414
416
415
if (backgroundEvictor_.size () && !fromBgThread &&
@@ -438,12 +437,12 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
438
437
handle = acquire (new (memory) Item (key, size, creationTime, expiryTime));
439
438
if (handle) {
440
439
handle.markNascent ();
441
- (*stats_.fragmentationSize )[pid][cid].add (
440
+ (*stats_.fragmentationSize )[tid][ pid][cid].add (
442
441
util::getFragmentation (*this , *handle));
443
442
}
444
443
445
444
} else { // failed to allocate memory.
446
- (*stats_.allocFailures )[pid][cid].inc (); // TODO: per-tier
445
+ (*stats_.allocFailures )[tid][ pid][cid].inc ();
447
446
// wake up rebalancer
448
447
if (!config_.poolRebalancerDisableForcedWakeUp && poolRebalancer_) {
449
448
poolRebalancer_->wakeUp ();
@@ -515,16 +514,14 @@ CacheAllocator<CacheTrait>::allocateChainedItemInternal(const Item& parent,
515
514
util::RollingLatencyTracker rollTracker{
516
515
(*stats_.classAllocLatency )[tid][pid][cid]};
517
516
518
- // TODO: per-tier? Right now stats_ are not used in any public periodic
519
- // worker
520
- (*stats_.allocAttempts )[pid][cid].inc ();
517
+ (*stats_.allocAttempts )[tid][pid][cid].inc ();
521
518
522
519
void * memory = allocator_[tid]->allocate (pid, requiredSize);
523
520
if (memory == nullptr ) {
524
521
memory = findEviction (tid, pid, cid);
525
522
}
526
523
if (memory == nullptr ) {
527
- (*stats_.allocFailures )[pid][cid].inc ();
524
+ (*stats_.allocFailures )[tid][ pid][cid].inc ();
528
525
return WriteHandle{};
529
526
}
530
527
@@ -535,7 +532,7 @@ CacheAllocator<CacheTrait>::allocateChainedItemInternal(const Item& parent,
535
532
536
533
if (child) {
537
534
child.markNascent ();
538
- (*stats_.fragmentationSize )[pid][cid].add (
535
+ (*stats_.fragmentationSize )[tid][ pid][cid].add (
539
536
util::getFragmentation (*this , *child));
540
537
}
541
538
@@ -874,7 +871,7 @@ CacheAllocator<CacheTrait>::releaseBackToAllocator(Item& it,
874
871
stats_.perPoolEvictionAgeSecs_ [allocInfo.poolId ].trackValue (refreshTime);
875
872
}
876
873
877
- (*stats_.fragmentationSize )[allocInfo.poolId ][allocInfo.classId ].sub (
874
+ (*stats_.fragmentationSize )[tid][ allocInfo.poolId ][allocInfo.classId ].sub (
878
875
util::getFragmentation (*this , it));
879
876
880
877
// Chained items can only end up in this place if the user has allocated
@@ -957,7 +954,7 @@ CacheAllocator<CacheTrait>::releaseBackToAllocator(Item& it,
957
954
958
955
const auto childInfo =
959
956
allocator_[tid]->getAllocInfo (static_cast <const void *>(head));
960
- (*stats_.fragmentationSize )[childInfo.poolId ][childInfo.classId ].sub (
957
+ (*stats_.fragmentationSize )[tid][ childInfo.poolId ][childInfo.classId ].sub (
961
958
util::getFragmentation (*this , *head));
962
959
963
960
removeFromMMContainer (*head);
@@ -1403,20 +1400,20 @@ CacheAllocator<CacheTrait>::getNextCandidate(TierId tid,
1403
1400
auto & mmContainer = getMMContainer (tid, pid, cid);
1404
1401
bool lastTier = tid+1 >= getNumTiers ();
1405
1402
1406
- mmContainer.withEvictionIterator ([this , pid, cid, &candidate, &toRecycle,
1403
+ mmContainer.withEvictionIterator ([this , tid, pid, cid, &candidate, &toRecycle,
1407
1404
&searchTries, &mmContainer, &lastTier,
1408
1405
&token](auto && itr) {
1409
1406
if (!itr) {
1410
1407
++searchTries;
1411
- (*stats_.evictionAttempts )[pid][cid].inc ();
1408
+ (*stats_.evictionAttempts )[tid][ pid][cid].inc ();
1412
1409
return ;
1413
1410
}
1414
1411
1415
1412
while ((config_.evictionSearchTries == 0 ||
1416
1413
config_.evictionSearchTries > searchTries) &&
1417
1414
itr) {
1418
1415
++searchTries;
1419
- (*stats_.evictionAttempts )[pid][cid].inc ();
1416
+ (*stats_.evictionAttempts )[tid][ pid][cid].inc ();
1420
1417
1421
1418
auto * toRecycle_ = itr.get ();
1422
1419
auto * candidate_ =
@@ -1522,6 +1519,7 @@ CacheAllocator<CacheTrait>::getNextCandidate(TierId tid,
1522
1519
XDCHECK (!candidate->isAccessible ());
1523
1520
XDCHECK (candidate->getKey () == evictedToNext->getKey ());
1524
1521
1522
+ (*stats_.numWritebacks )[tid][pid][cid].inc ();
1525
1523
wakeUpWaiters (candidate->getKey (), std::move (evictedToNext));
1526
1524
}
1527
1525
@@ -1549,9 +1547,9 @@ CacheAllocator<CacheTrait>::findEviction(TierId tid, PoolId pid, ClassId cid) {
1549
1547
// NULL. If `ref` == 0 then it means that we are the last holder of
1550
1548
// that item.
1551
1549
if (candidate->hasChainedItem ()) {
1552
- (*stats_.chainedItemEvictions )[pid][cid].inc ();
1550
+ (*stats_.chainedItemEvictions )[tid][ pid][cid].inc ();
1553
1551
} else {
1554
- (*stats_.regularItemEvictions )[pid][cid].inc ();
1552
+ (*stats_.regularItemEvictions )[tid][ pid][cid].inc ();
1555
1553
}
1556
1554
1557
1555
if (auto eventTracker = getEventTracker ()) {
@@ -2150,7 +2148,7 @@ bool CacheAllocator<CacheTrait>::recordAccessInMMContainer(Item& item,
2150
2148
const auto tid = getTierId (item);
2151
2149
const auto allocInfo =
2152
2150
allocator_[tid]->getAllocInfo (static_cast <const void *>(&item));
2153
- (*stats_.cacheHits )[allocInfo.poolId ][allocInfo.classId ].inc ();
2151
+ (*stats_.cacheHits )[tid][ allocInfo.poolId ][allocInfo.classId ].inc ();
2154
2152
2155
2153
// track recently accessed items if needed
2156
2154
if (UNLIKELY (config_.trackRecentItemsForDump )) {
@@ -2625,6 +2623,8 @@ size_t CacheAllocator<CacheTrait>::getPoolSize(PoolId poolId) const {
2625
2623
2626
2624
template <typename CacheTrait>
2627
2625
PoolStats CacheAllocator<CacheTrait>::getPoolStats(PoolId poolId) const {
2626
+ // this pool ref is just used to get class ids, which will be the
2627
+ // same across tiers
2628
2628
const auto & pool = allocator_[currentTier ()]->getPool (poolId);
2629
2629
const auto & allocSizes = pool.getAllocSizes ();
2630
2630
auto mpStats = pool.getStats ();
@@ -2643,24 +2643,42 @@ PoolStats CacheAllocator<CacheTrait>::getPoolStats(PoolId poolId) const {
2643
2643
// TODO export evictions, numItems etc from compact cache directly.
2644
2644
if (!isCompactCache) {
2645
2645
for (const ClassId cid : classIds) {
2646
- uint64_t classHits = (*stats_.cacheHits )[poolId][cid].get ();
2647
- XDCHECK (mmContainers_[currentTier ()][poolId][cid],
2648
- folly::sformat (" Pid {}, Cid {} not initialized." , poolId, cid));
2646
+ uint64_t allocAttempts = 0 , evictionAttempts = 0 , allocFailures = 0 ,
2647
+ fragmentationSize = 0 , classHits = 0 , chainedItemEvictions = 0 ,
2648
+ regularItemEvictions = 0 , numWritebacks = 0 ;
2649
+ MMContainerStat mmContainerStats;
2650
+ for (TierId tid = 0 ; tid < getNumTiers (); tid++) {
2651
+ allocAttempts += (*stats_.allocAttempts )[tid][poolId][cid].get ();
2652
+ evictionAttempts += (*stats_.evictionAttempts )[tid][poolId][cid].get ();
2653
+ allocFailures += (*stats_.allocFailures )[tid][poolId][cid].get ();
2654
+ fragmentationSize += (*stats_.fragmentationSize )[tid][poolId][cid].get ();
2655
+ classHits += (*stats_.cacheHits )[tid][poolId][cid].get ();
2656
+ chainedItemEvictions += (*stats_.chainedItemEvictions )[tid][poolId][cid].get ();
2657
+ regularItemEvictions += (*stats_.regularItemEvictions )[tid][poolId][cid].get ();
2658
+ numWritebacks += (*stats_.numWritebacks )[tid][poolId][cid].get ();
2659
+ mmContainerStats += getMMContainerStat (tid, poolId, cid);
2660
+ XDCHECK (mmContainers_[tid][poolId][cid],
2661
+ folly::sformat (" Tid {}, Pid {}, Cid {} not initialized." , tid, poolId, cid));
2662
+ }
2649
2663
cacheStats.insert (
2650
2664
{cid,
2651
- {allocSizes[cid], (*stats_.allocAttempts )[poolId][cid].get (),
2652
- (*stats_.evictionAttempts )[poolId][cid].get (),
2653
- (*stats_.allocFailures )[poolId][cid].get (),
2654
- (*stats_.fragmentationSize )[poolId][cid].get (), classHits,
2655
- (*stats_.chainedItemEvictions )[poolId][cid].get (),
2656
- (*stats_.regularItemEvictions )[poolId][cid].get (),
2657
- getMMContainerStat (currentTier (), poolId, cid)}});
2665
+ {allocSizes[cid],
2666
+ allocAttempts,
2667
+ evictionAttempts,
2668
+ allocFailures,
2669
+ fragmentationSize,
2670
+ classHits,
2671
+ chainedItemEvictions,
2672
+ regularItemEvictions,
2673
+ numWritebacks,
2674
+ mmContainerStats}});
2658
2675
totalHits += classHits;
2659
2676
}
2660
2677
}
2661
2678
2662
2679
PoolStats ret;
2663
2680
ret.isCompactCache = isCompactCache;
2681
+ // pool name is also shared among tiers
2664
2682
ret.poolName = allocator_[currentTier ()]->getPoolName (poolId);
2665
2683
ret.poolSize = pool.getPoolSize ();
2666
2684
ret.poolUsableSize = pool.getPoolUsableSize ();
@@ -2673,6 +2691,60 @@ PoolStats CacheAllocator<CacheTrait>::getPoolStats(PoolId poolId) const {
2673
2691
return ret;
2674
2692
}
2675
2693
2694
+ template <typename CacheTrait>
2695
+ PoolStats CacheAllocator<CacheTrait>::getPoolStats(TierId tid, PoolId poolId) const {
2696
+ const auto & pool = allocator_[tid]->getPool (poolId);
2697
+ const auto & allocSizes = pool.getAllocSizes ();
2698
+ auto mpStats = pool.getStats ();
2699
+ const auto & classIds = mpStats.classIds ;
2700
+
2701
+ // check if this is a compact cache.
2702
+ bool isCompactCache = false ;
2703
+ {
2704
+ std::shared_lock lock (compactCachePoolsLock_);
2705
+ isCompactCache = isCompactCachePool_[poolId];
2706
+ }
2707
+
2708
+ // std::unordered_map<ClassId, CacheStat> cacheStats;
2709
+ folly::F14FastMap<ClassId, CacheStat> cacheStats;
2710
+ uint64_t totalHits = 0 ;
2711
+ // cacheStats is only menaningful for pools that are not compact caches.
2712
+ // TODO export evictions, numItems etc from compact cache directly.
2713
+ if (!isCompactCache) {
2714
+ for (const ClassId cid : classIds) {
2715
+ uint64_t classHits = (*stats_.cacheHits )[tid][poolId][cid].get ();
2716
+ XDCHECK (mmContainers_[tid][poolId][cid],
2717
+ folly::sformat (" Tid {}, Pid {}, Cid {} not initialized." , tid, poolId, cid));
2718
+ cacheStats.insert (
2719
+ {cid,
2720
+ {allocSizes[cid],
2721
+ (*stats_.allocAttempts )[tid][poolId][cid].get (),
2722
+ (*stats_.evictionAttempts )[tid][poolId][cid].get (),
2723
+ (*stats_.allocFailures )[tid][poolId][cid].get (),
2724
+ (*stats_.fragmentationSize )[tid][poolId][cid].get (),
2725
+ classHits,
2726
+ (*stats_.chainedItemEvictions )[tid][poolId][cid].get (),
2727
+ (*stats_.regularItemEvictions )[tid][poolId][cid].get (),
2728
+ (*stats_.numWritebacks )[tid][poolId][cid].get (),
2729
+ getMMContainerStat (tid, poolId, cid)}});
2730
+ totalHits += classHits;
2731
+ }
2732
+ }
2733
+
2734
+ PoolStats ret;
2735
+ ret.isCompactCache = isCompactCache;
2736
+ ret.poolName = allocator_[tid]->getPoolName (poolId);
2737
+ ret.poolSize = pool.getPoolSize ();
2738
+ ret.poolUsableSize = pool.getPoolUsableSize ();
2739
+ ret.poolAdvisedSize = pool.getPoolAdvisedSize ();
2740
+ ret.cacheStats = std::move (cacheStats);
2741
+ ret.mpStats = std::move (mpStats);
2742
+ ret.numPoolGetHits = totalHits;
2743
+ ret.evictionAgeSecs = stats_.perPoolEvictionAgeSecs_ [poolId].estimate ();
2744
+
2745
+ return ret;
2746
+ }
2747
+
2676
2748
template <typename CacheTrait>
2677
2749
ACStats CacheAllocator<CacheTrait>::getACStats(TierId tid,
2678
2750
PoolId poolId,
@@ -2918,7 +2990,7 @@ bool CacheAllocator<CacheTrait>::moveForSlabRelease(Item& oldItem) {
2918
2990
}
2919
2991
allocator_[tid]->free (&oldItem);
2920
2992
2921
- (*stats_.fragmentationSize )[allocInfo.poolId ][allocInfo.classId ].sub (
2993
+ (*stats_.fragmentationSize )[tid][ allocInfo.poolId ][allocInfo.classId ].sub (
2922
2994
util::getFragmentation (*this , oldItem));
2923
2995
stats_.numMoveSuccesses .inc ();
2924
2996
return true ;
@@ -2993,12 +3065,13 @@ void CacheAllocator<CacheTrait>::evictForSlabRelease(Item& item) {
2993
3065
nvmCache_->put (*evicted, std::move (token));
2994
3066
}
2995
3067
3068
+ const auto tid = getTierId (*evicted);
2996
3069
const auto allocInfo =
2997
- allocator_[getTierId (item) ]->getAllocInfo (static_cast <const void *>(&item ));
3070
+ allocator_[tid ]->getAllocInfo (static_cast <const void *>(evicted ));
2998
3071
if (evicted->hasChainedItem ()) {
2999
- (*stats_.chainedItemEvictions )[allocInfo.poolId ][allocInfo.classId ].inc ();
3072
+ (*stats_.chainedItemEvictions )[tid][ allocInfo.poolId ][allocInfo.classId ].inc ();
3000
3073
} else {
3001
- (*stats_.regularItemEvictions )[allocInfo.poolId ][allocInfo.classId ].inc ();
3074
+ (*stats_.regularItemEvictions )[tid][ allocInfo.poolId ][allocInfo.classId ].inc ();
3002
3075
}
3003
3076
3004
3077
stats_.numEvictionSuccesses .inc ();
@@ -3232,8 +3305,13 @@ folly::IOBufQueue CacheAllocator<CacheTrait>::saveStateToIOBuf() {
3232
3305
for (PoolId pid : pools) {
3233
3306
for (unsigned int cid = 0 ; cid < (*stats_.fragmentationSize )[pid].size ();
3234
3307
++cid) {
3308
+ uint64_t fragmentationSize = 0 ;
3309
+ for (TierId tid = 0 ; tid < getNumTiers (); tid++) {
3310
+ fragmentationSize += (*stats_.fragmentationSize )[tid][pid][cid].get ();
3311
+ }
3235
3312
metadata_.fragmentationSize ()[pid][static_cast <ClassId>(cid)] =
3236
- (*stats_.fragmentationSize )[pid][cid].get ();
3313
+ fragmentationSize;
3314
+
3237
3315
}
3238
3316
if (isCompactCachePool_[pid]) {
3239
3317
metadata_.compactCachePools ()->push_back (pid);
@@ -3479,8 +3557,19 @@ void CacheAllocator<CacheTrait>::initStats() {
3479
3557
// deserialize the fragmentation size of each thread.
3480
3558
for (const auto & pid : *metadata_.fragmentationSize ()) {
3481
3559
for (const auto & cid : pid.second ) {
3482
- (*stats_.fragmentationSize )[pid.first ][cid.first ].set (
3483
- static_cast <uint64_t >(cid.second ));
3560
+ // in multi-tier we serialized as the sum - no way
3561
+ // to get back so just divide the two for now
3562
+ // TODO: proper multi-tier serialization
3563
+ uint64_t total = static_cast <uint64_t >(cid.second );
3564
+ uint64_t part = total / getNumTiers ();
3565
+ uint64_t sum = 0 ;
3566
+ for (TierId tid = 1 ; tid < getNumTiers (); tid++) {
3567
+ (*stats_.fragmentationSize )[tid][pid.first ][cid.first ].set (part);
3568
+ sum += part;
3569
+ }
3570
+ uint64_t leftover = total - sum;
3571
+ (*stats_.fragmentationSize )[0 ][pid.first ][cid.first ].set (leftover);
3572
+
3484
3573
}
3485
3574
}
3486
3575
0 commit comments