Skip to content

Commit dec1628

Browse files
committed
Background promotion
1 parent d5fc2b4 commit dec1628

File tree

11 files changed

+538
-23
lines changed

11 files changed

+538
-23
lines changed
Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
/*
2+
* Copyright (c) Intel and its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
18+
19+
namespace facebook {
20+
namespace cachelib {
21+
22+
23+
template <typename CacheT>
24+
BackgroundPromoter<CacheT>::BackgroundPromoter(Cache& cache,
25+
std::shared_ptr<BackgroundEvictorStrategy> strategy)
26+
: cache_(cache),
27+
strategy_(strategy)
28+
{
29+
}
30+
31+
template <typename CacheT>
32+
BackgroundPromoter<CacheT>::~BackgroundPromoter() { stop(std::chrono::seconds(0)); }
33+
34+
template <typename CacheT>
35+
void BackgroundPromoter<CacheT>::work() {
36+
try {
37+
checkAndRun();
38+
} catch (const std::exception& ex) {
39+
XLOGF(ERR, "BackgroundPromoter interrupted due to exception: {}", ex.what());
40+
}
41+
}
42+
43+
template <typename CacheT>
44+
void BackgroundPromoter<CacheT>::setAssignedMemory(std::vector<std::tuple<TierId, PoolId, ClassId>> &&assignedMemory)
45+
{
46+
XLOG(INFO, "Memory assigned to background worker:");
47+
for (auto [tid, pid, cid] : assignedMemory) {
48+
XLOGF(INFO, "Tid: {}, Pid: {}, Cid: {}", tid, pid, cid);
49+
}
50+
51+
mutex.lock_combine([this, &assignedMemory]{
52+
this->assignedMemory_ = std::move(assignedMemory);
53+
});
54+
}
55+
56+
// Look for classes that exceed the target memory capacity
57+
// and return those for eviction
58+
template <typename CacheT>
59+
void BackgroundPromoter<CacheT>::checkAndRun() {
60+
auto assignedMemory = mutex.lock_combine([this]{
61+
return assignedMemory_;
62+
});
63+
64+
unsigned int evictions = 0;
65+
std::set<ClassId> classes{};
66+
67+
for (const auto [tid, pid, cid] : assignedMemory) {
68+
classes.insert(cid);
69+
const auto& mpStats = cache_.getPoolByTid(pid,tid).getStats();
70+
auto batch = strategy_->calculateBatchSize(cache_,tid,pid,cid);
71+
if (!batch) {
72+
continue;
73+
}
74+
75+
// stats.evictionSize.add(batch * mpStats.acStats.at(cid).allocSize);
76+
77+
//try evicting BATCH items from the class in order to reach free target
78+
auto evicted =
79+
BackgroundPromoterAPIWrapper<CacheT>::traverseAndPromoteItems(cache_,
80+
tid,pid,cid,batch);
81+
evictions += evicted;
82+
83+
const size_t cid_id = (size_t)mpStats.acStats.at(cid).allocSize;
84+
auto it = evictions_per_class_.find(cid_id);
85+
if (it != evictions_per_class_.end()) {
86+
it->second += evicted;
87+
} else {
88+
evictions_per_class_[cid_id] = 0;
89+
}
90+
}
91+
92+
// stats.numTraversals.inc();
93+
// stats.numPromotedItems.add(promotions);
94+
// stats.totalClasses.add(classes.size());
95+
}
96+
97+
// template <typename CacheT>
98+
// BackgroundPromotionStats BackgroundPromoter<CacheT>::getStats() const noexcept {
99+
// BackgroundPromotionStats evicStats;
100+
// evicStats.numPromotedItems = stats.numPromotedItems.get();
101+
// evicStats.runCount = stats.numTraversals.get();
102+
// evicStats.evictionSize = stats.evictionSize.get();
103+
// evicStats.totalClasses = stats.totalClasses.get();
104+
105+
// return evicStats;
106+
// }
107+
108+
// template <typename CacheT>
109+
// std::map<uint32_t,uint64_t> BackgroundPromoter<CacheT>::getClassStats() const noexcept {
110+
// return evictions_per_class_;
111+
// }
112+
113+
} // namespace cachelib
114+
} // namespace facebook
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
/*
2+
* Copyright (c) Intel and its affiliates.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
#pragma once
18+
19+
#include <gtest/gtest_prod.h>
20+
#include <folly/concurrency/UnboundedQueue.h>
21+
22+
#include "cachelib/allocator/CacheStats.h"
23+
#include "cachelib/common/PeriodicWorker.h"
24+
#include "cachelib/allocator/BackgroundEvictorStrategy.h"
25+
#include "cachelib/common/AtomicCounter.h"
26+
27+
28+
namespace facebook {
29+
namespace cachelib {
30+
31+
// wrapper that exposes the private APIs of CacheType that are specifically
32+
// needed for the promotion.
33+
template <typename C>
34+
struct BackgroundPromoterAPIWrapper {
35+
36+
static size_t traverseAndPromoteItems(C& cache,
37+
unsigned int tid, unsigned int pid, unsigned int cid, size_t batch) {
38+
return cache.traverseAndPromoteItems(tid,pid,cid,batch);
39+
}
40+
};
41+
42+
struct BackgroundPromoterStats {
43+
// items evicted
44+
AtomicCounter numPromotedItems{0};
45+
46+
// traversals
47+
AtomicCounter numTraversals{0};
48+
49+
// total class size
50+
AtomicCounter totalClasses{0};
51+
52+
// item eviction size
53+
AtomicCounter promotionSize{0};
54+
};
55+
56+
template <typename CacheT>
57+
class BackgroundPromoter : public PeriodicWorker {
58+
public:
59+
using Cache = CacheT;
60+
// @param cache the cache interface
61+
// @param target_free the target amount of memory to keep free in
62+
// this tier
63+
// @param tier id memory tier to perform promotin from
64+
BackgroundPromoter(Cache& cache,
65+
std::shared_ptr<BackgroundEvictorStrategy> strategy);
66+
// TODO: use separate strategy for eviction and promotion
67+
68+
~BackgroundPromoter() override;
69+
70+
// TODO
71+
//BackgroundPromotionStats getStats() const noexcept;
72+
//std::map<uint32_t,uint64_t> getClassStats() const noexcept;
73+
74+
void setAssignedMemory(std::vector<std::tuple<TierId, PoolId, ClassId>> &&assignedMemory);
75+
76+
private:
77+
std::map<uint32_t,uint64_t> evictions_per_class_;
78+
79+
// cache allocator's interface for evicting
80+
81+
using Item = typename Cache::Item;
82+
83+
Cache& cache_;
84+
std::shared_ptr<BackgroundEvictorStrategy> strategy_;
85+
86+
// implements the actual logic of running the background evictor
87+
void work() override final;
88+
void checkAndRun();
89+
90+
// BackgrounPromoterStats stats;
91+
92+
std::vector<std::tuple<TierId, PoolId, ClassId>> assignedMemory_;
93+
folly::DistributedMutex mutex;
94+
};
95+
} // namespace cachelib
96+
} // namespace facebook
97+
98+
#include "cachelib/allocator/BackgroundPromoter-inl.h"

0 commit comments

Comments
 (0)