@@ -417,8 +417,7 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
417
417
util::RollingLatencyTracker rollTracker{
418
418
(*stats_.classAllocLatency )[tid][pid][cid]};
419
419
420
- // TODO: per-tier
421
- (*stats_.allocAttempts )[pid][cid].inc ();
420
+ (*stats_.allocAttempts )[tid][pid][cid].inc ();
422
421
423
422
void * memory = allocator_[tid]->allocate (pid, requiredSize);
424
423
@@ -444,12 +443,12 @@ CacheAllocator<CacheTrait>::allocateInternalTier(TierId tid,
444
443
handle = acquire (new (memory) Item (key, size, creationTime, expiryTime));
445
444
if (handle) {
446
445
handle.markNascent ();
447
- (*stats_.fragmentationSize )[pid][cid].add (
446
+ (*stats_.fragmentationSize )[tid][ pid][cid].add (
448
447
util::getFragmentation (*this , *handle));
449
448
}
450
449
451
450
} else { // failed to allocate memory.
452
- (*stats_.allocFailures )[pid][cid].inc (); // TODO: per-tier
451
+ (*stats_.allocFailures )[tid][ pid][cid].inc ();
453
452
// wake up rebalancer
454
453
if (!config_.poolRebalancerDisableForcedWakeUp && poolRebalancer_) {
455
454
poolRebalancer_->wakeUp ();
@@ -521,16 +520,14 @@ CacheAllocator<CacheTrait>::allocateChainedItemInternal(
521
520
util::RollingLatencyTracker rollTracker{
522
521
(*stats_.classAllocLatency )[tid][pid][cid]};
523
522
524
- // TODO: per-tier? Right now stats_ are not used in any public periodic
525
- // worker
526
- (*stats_.allocAttempts )[pid][cid].inc ();
523
+ (*stats_.allocAttempts )[tid][pid][cid].inc ();
527
524
528
525
void * memory = allocator_[tid]->allocate (pid, requiredSize);
529
526
if (memory == nullptr ) {
530
527
memory = findEviction (tid, pid, cid);
531
528
}
532
529
if (memory == nullptr ) {
533
- (*stats_.allocFailures )[pid][cid].inc ();
530
+ (*stats_.allocFailures )[tid][ pid][cid].inc ();
534
531
return WriteHandle{};
535
532
}
536
533
@@ -542,7 +539,7 @@ CacheAllocator<CacheTrait>::allocateChainedItemInternal(
542
539
543
540
if (child) {
544
541
child.markNascent ();
545
- (*stats_.fragmentationSize )[pid][cid].add (
542
+ (*stats_.fragmentationSize )[tid][ pid][cid].add (
546
543
util::getFragmentation (*this , *child));
547
544
}
548
545
@@ -857,7 +854,7 @@ CacheAllocator<CacheTrait>::releaseBackToAllocator(Item& it,
857
854
stats_.perPoolEvictionAgeSecs_ [allocInfo.poolId ].trackValue (refreshTime);
858
855
}
859
856
860
- (*stats_.fragmentationSize )[allocInfo.poolId ][allocInfo.classId ].sub (
857
+ (*stats_.fragmentationSize )[tid][ allocInfo.poolId ][allocInfo.classId ].sub (
861
858
util::getFragmentation (*this , it));
862
859
863
860
// Chained items can only end up in this place if the user has allocated
@@ -940,7 +937,7 @@ CacheAllocator<CacheTrait>::releaseBackToAllocator(Item& it,
940
937
941
938
const auto childInfo =
942
939
allocator_[tid]->getAllocInfo (static_cast <const void *>(head));
943
- (*stats_.fragmentationSize )[childInfo.poolId ][childInfo.classId ].sub (
940
+ (*stats_.fragmentationSize )[tid][ childInfo.poolId ][childInfo.classId ].sub (
944
941
util::getFragmentation (*this , *head));
945
942
946
943
removeFromMMContainer (*head);
@@ -1582,20 +1579,20 @@ CacheAllocator<CacheTrait>::getNextCandidate(TierId tid,
1582
1579
auto & mmContainer = getMMContainer (tid, pid, cid);
1583
1580
bool lastTier = tid+1 >= getNumTiers ();
1584
1581
1585
- mmContainer.withEvictionIterator ([this , pid, cid, &candidate, &toRecycle,
1582
+ mmContainer.withEvictionIterator ([this , tid, pid, cid, &candidate, &toRecycle,
1586
1583
&searchTries, &mmContainer, &lastTier,
1587
1584
&token](auto && itr) {
1588
1585
if (!itr) {
1589
1586
++searchTries;
1590
- (*stats_.evictionAttempts )[pid][cid].inc ();
1587
+ (*stats_.evictionAttempts )[tid][ pid][cid].inc ();
1591
1588
return ;
1592
1589
}
1593
1590
1594
1591
while ((config_.evictionSearchTries == 0 ||
1595
1592
config_.evictionSearchTries > searchTries) &&
1596
1593
itr) {
1597
1594
++searchTries;
1598
- (*stats_.evictionAttempts )[pid][cid].inc ();
1595
+ (*stats_.evictionAttempts )[tid][ pid][cid].inc ();
1599
1596
1600
1597
auto * toRecycle_ = itr.get ();
1601
1598
auto * candidate_ =
@@ -1701,6 +1698,7 @@ CacheAllocator<CacheTrait>::getNextCandidate(TierId tid,
1701
1698
XDCHECK (!candidate->isAccessible ());
1702
1699
XDCHECK (candidate->getKey () == evictedToNext->getKey ());
1703
1700
1701
+ (*stats_.numWritebacks )[tid][pid][cid].inc ();
1704
1702
wakeUpWaiters (*candidate, std::move (evictedToNext));
1705
1703
}
1706
1704
@@ -1728,9 +1726,9 @@ CacheAllocator<CacheTrait>::findEviction(TierId tid, PoolId pid, ClassId cid) {
1728
1726
// NULL. If `ref` == 0 then it means that we are the last holder of
1729
1727
// that item.
1730
1728
if (candidate->hasChainedItem ()) {
1731
- (*stats_.chainedItemEvictions )[pid][cid].inc ();
1729
+ (*stats_.chainedItemEvictions )[tid][ pid][cid].inc ();
1732
1730
} else {
1733
- (*stats_.regularItemEvictions )[pid][cid].inc ();
1731
+ (*stats_.regularItemEvictions )[tid][ pid][cid].inc ();
1734
1732
}
1735
1733
1736
1734
if (auto eventTracker = getEventTracker ()) {
@@ -2333,7 +2331,7 @@ bool CacheAllocator<CacheTrait>::recordAccessInMMContainer(Item& item,
2333
2331
const auto tid = getTierId (item);
2334
2332
const auto allocInfo =
2335
2333
allocator_[tid]->getAllocInfo (static_cast <const void *>(&item));
2336
- (*stats_.cacheHits )[allocInfo.poolId ][allocInfo.classId ].inc ();
2334
+ (*stats_.cacheHits )[tid][ allocInfo.poolId ][allocInfo.classId ].inc ();
2337
2335
2338
2336
// track recently accessed items if needed
2339
2337
if (UNLIKELY (config_.trackRecentItemsForDump )) {
@@ -2802,6 +2800,8 @@ size_t CacheAllocator<CacheTrait>::getPoolSize(PoolId poolId) const {
2802
2800
2803
2801
template <typename CacheTrait>
2804
2802
PoolStats CacheAllocator<CacheTrait>::getPoolStats(PoolId poolId) const {
2803
+ // this pool ref is just used to get class ids, which will be the
2804
+ // same across tiers
2805
2805
const auto & pool = allocator_[currentTier ()]->getPool (poolId);
2806
2806
const auto & allocSizes = pool.getAllocSizes ();
2807
2807
auto mpStats = pool.getStats ();
@@ -2820,24 +2820,42 @@ PoolStats CacheAllocator<CacheTrait>::getPoolStats(PoolId poolId) const {
2820
2820
// TODO export evictions, numItems etc from compact cache directly.
2821
2821
if (!isCompactCache) {
2822
2822
for (const ClassId cid : classIds) {
2823
- uint64_t classHits = (*stats_.cacheHits )[poolId][cid].get ();
2824
- XDCHECK (mmContainers_[currentTier ()][poolId][cid],
2825
- folly::sformat (" Pid {}, Cid {} not initialized." , poolId, cid));
2823
+ uint64_t allocAttempts = 0 , evictionAttempts = 0 , allocFailures = 0 ,
2824
+ fragmentationSize = 0 , classHits = 0 , chainedItemEvictions = 0 ,
2825
+ regularItemEvictions = 0 , numWritebacks = 0 ;
2826
+ MMContainerStat mmContainerStats;
2827
+ for (TierId tid = 0 ; tid < getNumTiers (); tid++) {
2828
+ allocAttempts += (*stats_.allocAttempts )[tid][poolId][cid].get ();
2829
+ evictionAttempts += (*stats_.evictionAttempts )[tid][poolId][cid].get ();
2830
+ allocFailures += (*stats_.allocFailures )[tid][poolId][cid].get ();
2831
+ fragmentationSize += (*stats_.fragmentationSize )[tid][poolId][cid].get ();
2832
+ classHits += (*stats_.cacheHits )[tid][poolId][cid].get ();
2833
+ chainedItemEvictions += (*stats_.chainedItemEvictions )[tid][poolId][cid].get ();
2834
+ regularItemEvictions += (*stats_.regularItemEvictions )[tid][poolId][cid].get ();
2835
+ numWritebacks += (*stats_.numWritebacks )[tid][poolId][cid].get ();
2836
+ mmContainerStats += getMMContainerStat (tid, poolId, cid);
2837
+ XDCHECK (mmContainers_[tid][poolId][cid],
2838
+ folly::sformat (" Tid {}, Pid {}, Cid {} not initialized." , tid, poolId, cid));
2839
+ }
2826
2840
cacheStats.insert (
2827
2841
{cid,
2828
- {allocSizes[cid], (*stats_.allocAttempts )[poolId][cid].get (),
2829
- (*stats_.evictionAttempts )[poolId][cid].get (),
2830
- (*stats_.allocFailures )[poolId][cid].get (),
2831
- (*stats_.fragmentationSize )[poolId][cid].get (), classHits,
2832
- (*stats_.chainedItemEvictions )[poolId][cid].get (),
2833
- (*stats_.regularItemEvictions )[poolId][cid].get (),
2834
- getMMContainerStat (currentTier (), poolId, cid)}});
2842
+ {allocSizes[cid],
2843
+ allocAttempts,
2844
+ evictionAttempts,
2845
+ allocFailures,
2846
+ fragmentationSize,
2847
+ classHits,
2848
+ chainedItemEvictions,
2849
+ regularItemEvictions,
2850
+ numWritebacks,
2851
+ mmContainerStats}});
2835
2852
totalHits += classHits;
2836
2853
}
2837
2854
}
2838
2855
2839
2856
PoolStats ret;
2840
2857
ret.isCompactCache = isCompactCache;
2858
+ // pool name is also shared among tiers
2841
2859
ret.poolName = allocator_[currentTier ()]->getPoolName (poolId);
2842
2860
ret.poolSize = pool.getPoolSize ();
2843
2861
ret.poolUsableSize = pool.getPoolUsableSize ();
@@ -2850,6 +2868,59 @@ PoolStats CacheAllocator<CacheTrait>::getPoolStats(PoolId poolId) const {
2850
2868
return ret;
2851
2869
}
2852
2870
2871
+ template <typename CacheTrait>
2872
+ PoolStats CacheAllocator<CacheTrait>::getPoolStats(TierId tid, PoolId poolId) const {
2873
+ const auto & pool = allocator_[tid]->getPool (poolId);
2874
+ const auto & allocSizes = pool.getAllocSizes ();
2875
+ auto mpStats = pool.getStats ();
2876
+ const auto & classIds = mpStats.classIds ;
2877
+
2878
+ // check if this is a compact cache.
2879
+ bool isCompactCache = false ;
2880
+ {
2881
+ folly::SharedMutex::ReadHolder lock (compactCachePoolsLock_);
2882
+ isCompactCache = isCompactCachePool_[poolId];
2883
+ }
2884
+
2885
+ std::unordered_map<ClassId, CacheStat> cacheStats;
2886
+ uint64_t totalHits = 0 ;
2887
+ // cacheStats is only menaningful for pools that are not compact caches.
2888
+ // TODO export evictions, numItems etc from compact cache directly.
2889
+ if (!isCompactCache) {
2890
+ for (const ClassId cid : classIds) {
2891
+ uint64_t classHits = (*stats_.cacheHits )[tid][poolId][cid].get ();
2892
+ XDCHECK (mmContainers_[tid][poolId][cid],
2893
+ folly::sformat (" Tid {}, Pid {}, Cid {} not initialized." , tid, poolId, cid));
2894
+ cacheStats.insert (
2895
+ {cid,
2896
+ {allocSizes[cid],
2897
+ (*stats_.allocAttempts )[tid][poolId][cid].get (),
2898
+ (*stats_.evictionAttempts )[tid][poolId][cid].get (),
2899
+ (*stats_.allocFailures )[tid][poolId][cid].get (),
2900
+ (*stats_.fragmentationSize )[tid][poolId][cid].get (),
2901
+ classHits,
2902
+ (*stats_.chainedItemEvictions )[tid][poolId][cid].get (),
2903
+ (*stats_.regularItemEvictions )[tid][poolId][cid].get (),
2904
+ (*stats_.numWritebacks )[tid][poolId][cid].get (),
2905
+ getMMContainerStat (tid, poolId, cid)}});
2906
+ totalHits += classHits;
2907
+ }
2908
+ }
2909
+
2910
+ PoolStats ret;
2911
+ ret.isCompactCache = isCompactCache;
2912
+ ret.poolName = allocator_[tid]->getPoolName (poolId);
2913
+ ret.poolSize = pool.getPoolSize ();
2914
+ ret.poolUsableSize = pool.getPoolUsableSize ();
2915
+ ret.poolAdvisedSize = pool.getPoolAdvisedSize ();
2916
+ ret.cacheStats = std::move (cacheStats);
2917
+ ret.mpStats = std::move (mpStats);
2918
+ ret.numPoolGetHits = totalHits;
2919
+ ret.evictionAgeSecs = stats_.perPoolEvictionAgeSecs_ [poolId].estimate ();
2920
+
2921
+ return ret;
2922
+ }
2923
+
2853
2924
template <typename CacheTrait>
2854
2925
ACStats CacheAllocator<CacheTrait>::getACStats(TierId tid,
2855
2926
PoolId poolId,
@@ -3100,7 +3171,7 @@ bool CacheAllocator<CacheTrait>::moveForSlabRelease(
3100
3171
const auto allocInfo = allocator_[tid]->getAllocInfo (oldItem.getMemory ());
3101
3172
allocator_[tid]->free (&oldItem);
3102
3173
3103
- (*stats_.fragmentationSize )[allocInfo.poolId ][allocInfo.classId ].sub (
3174
+ (*stats_.fragmentationSize )[tid][ allocInfo.poolId ][allocInfo.classId ].sub (
3104
3175
util::getFragmentation (*this , oldItem));
3105
3176
stats_.numMoveSuccesses .inc ();
3106
3177
return true ;
@@ -3379,12 +3450,13 @@ void CacheAllocator<CacheTrait>::evictForSlabRelease(
3379
3450
nvmCache_->put (*evicted, std::move (token));
3380
3451
}
3381
3452
3453
+ const auto tid = getTierId (*evicted);
3382
3454
const auto allocInfo =
3383
- allocator_[getTierId (*evicted) ]->getAllocInfo (static_cast <const void *>(evicted));
3455
+ allocator_[tid ]->getAllocInfo (static_cast <const void *>(evicted));
3384
3456
if (evicted->hasChainedItem ()) {
3385
- (*stats_.chainedItemEvictions )[allocInfo.poolId ][allocInfo.classId ].inc ();
3457
+ (*stats_.chainedItemEvictions )[tid][ allocInfo.poolId ][allocInfo.classId ].inc ();
3386
3458
} else {
3387
- (*stats_.regularItemEvictions )[allocInfo.poolId ][allocInfo.classId ].inc ();
3459
+ (*stats_.regularItemEvictions )[tid][ allocInfo.poolId ][allocInfo.classId ].inc ();
3388
3460
}
3389
3461
3390
3462
stats_.numEvictionSuccesses .inc ();
@@ -3607,8 +3679,13 @@ folly::IOBufQueue CacheAllocator<CacheTrait>::saveStateToIOBuf() {
3607
3679
for (PoolId pid : pools) {
3608
3680
for (unsigned int cid = 0 ; cid < (*stats_.fragmentationSize )[pid].size ();
3609
3681
++cid) {
3682
+ uint64_t fragmentationSize = 0 ;
3683
+ for (TierId tid = 0 ; tid < getNumTiers (); tid++) {
3684
+ fragmentationSize += (*stats_.fragmentationSize )[tid][pid][cid].get ();
3685
+ }
3610
3686
metadata_.fragmentationSize ()[pid][static_cast <ClassId>(cid)] =
3611
- (*stats_.fragmentationSize )[pid][cid].get ();
3687
+ fragmentationSize;
3688
+
3612
3689
}
3613
3690
if (isCompactCachePool_[pid]) {
3614
3691
metadata_.compactCachePools ()->push_back (pid);
@@ -3854,8 +3931,19 @@ void CacheAllocator<CacheTrait>::initStats() {
3854
3931
// deserialize the fragmentation size of each thread.
3855
3932
for (const auto & pid : *metadata_.fragmentationSize ()) {
3856
3933
for (const auto & cid : pid.second ) {
3857
- (*stats_.fragmentationSize )[pid.first ][cid.first ].set (
3858
- static_cast <uint64_t >(cid.second ));
3934
+ // in multi-tier we serialized as the sum - no way
3935
+ // to get back so just divide the two for now
3936
+ // TODO: proper multi-tier serialization
3937
+ uint64_t total = static_cast <uint64_t >(cid.second );
3938
+ uint64_t part = total / getNumTiers ();
3939
+ uint64_t sum = 0 ;
3940
+ for (TierId tid = 1 ; tid < getNumTiers (); tid++) {
3941
+ (*stats_.fragmentationSize )[tid][pid.first ][cid.first ].set (part);
3942
+ sum += part;
3943
+ }
3944
+ uint64_t leftover = total - sum;
3945
+ (*stats_.fragmentationSize )[0 ][pid.first ][cid.first ].set (leftover);
3946
+
3859
3947
}
3860
3948
}
3861
3949
0 commit comments