Skip to content

Commit 0fe363a

Browse files
byrnedjigchor
authored andcommitted
Initial framework for background item eviction/promotion
Implement stubs for periodic workers for item eviction/promotion. Actual implementation of eviction and promotion will be provided in the next patch. The idea behing introducing those workers is the following: - BG eviction: to keep certain amount of free memory and decreasing allocate latency - BG promotion: to move hot items to memory decresing latency
1 parent 519f664 commit 0fe363a

14 files changed

+777
-9
lines changed
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
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+
namespace facebook {
18+
namespace cachelib {
19+
20+
template <typename CacheT>
21+
BackgroundMover<CacheT>::BackgroundMover(
22+
Cache& cache,
23+
std::shared_ptr<BackgroundMoverStrategy> strategy,
24+
MoverDir direction)
25+
: cache_(cache), strategy_(strategy), direction_(direction) {
26+
if (direction_ == MoverDir::Evict) {
27+
moverFunc = BackgroundMoverAPIWrapper<CacheT>::traverseAndEvictItems;
28+
29+
} else if (direction_ == MoverDir::Promote) {
30+
moverFunc = BackgroundMoverAPIWrapper<CacheT>::traverseAndPromoteItems;
31+
}
32+
}
33+
34+
template <typename CacheT>
35+
BackgroundMover<CacheT>::~BackgroundMover() {
36+
stop(std::chrono::seconds(0));
37+
}
38+
39+
template <typename CacheT>
40+
void BackgroundMover<CacheT>::work() {
41+
try {
42+
checkAndRun();
43+
} catch (const std::exception& ex) {
44+
XLOGF(ERR, "BackgroundMover interrupted due to exception: {}", ex.what());
45+
}
46+
}
47+
48+
template <typename CacheT>
49+
void BackgroundMover<CacheT>::setAssignedMemory(
50+
std::vector<MemoryDescriptorType>&& assignedMemory) {
51+
XLOG(INFO, "Class assigned to background worker:");
52+
for (auto [pid, cid] : assignedMemory) {
53+
XLOGF(INFO, "Pid: {}, Cid: {}", pid, cid);
54+
}
55+
56+
mutex.lock_combine([this, &assignedMemory] {
57+
this->assignedMemory_ = std::move(assignedMemory);
58+
});
59+
}
60+
61+
// Look for classes that exceed the target memory capacity
62+
// and return those for eviction
63+
template <typename CacheT>
64+
void BackgroundMover<CacheT>::checkAndRun() {
65+
auto assignedMemory = mutex.lock_combine([this] { return assignedMemory_; });
66+
67+
unsigned int moves = 0;
68+
std::set<ClassId> classes{};
69+
auto batches = strategy_->calculateBatchSizes(cache_, assignedMemory);
70+
71+
for (size_t i = 0; i < batches.size(); i++) {
72+
const auto [pid, cid] = assignedMemory[i];
73+
const auto batch = batches[i];
74+
75+
classes.insert(cid);
76+
const auto& mpStats = cache_.getPool(pid).getStats();
77+
78+
if (!batch) {
79+
continue;
80+
}
81+
82+
// try moving BATCH items from the class in order to reach free target
83+
auto moved = moverFunc(cache_, pid, cid, batch);
84+
moves += moved;
85+
moves_per_class_[pid][cid] += moved;
86+
totalBytesMoved.add(moved * mpStats.acStats.at(cid).allocSize);
87+
}
88+
89+
numTraversals.inc();
90+
numMovedItems.add(moves);
91+
totalClasses.add(classes.size());
92+
}
93+
94+
template <typename CacheT>
95+
BackgroundMoverStats BackgroundMover<CacheT>::getStats() const noexcept {
96+
BackgroundMoverStats stats;
97+
stats.numMovedItems = numMovedItems.get();
98+
stats.runCount = numTraversals.get();
99+
stats.totalBytesMoved = totalBytesMoved.get();
100+
stats.totalClasses = totalClasses.get();
101+
102+
return stats;
103+
}
104+
105+
template <typename CacheT>
106+
std::map<PoolId, std::map<ClassId, uint64_t>>
107+
BackgroundMover<CacheT>::getClassStats() const noexcept {
108+
return moves_per_class_;
109+
}
110+
111+
} // namespace cachelib
112+
} // namespace facebook

cachelib/allocator/BackgroundMover.h

Lines changed: 96 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
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 "cachelib/allocator/BackgroundMoverStrategy.h"
20+
#include "cachelib/allocator/CacheStats.h"
21+
#include "cachelib/common/AtomicCounter.h"
22+
#include "cachelib/common/PeriodicWorker.h"
23+
24+
namespace facebook {
25+
namespace cachelib {
26+
27+
// wrapper that exposes the private APIs of CacheType that are specifically
28+
// needed for the cache api
29+
template <typename C>
30+
struct BackgroundMoverAPIWrapper {
31+
static size_t traverseAndEvictItems(C& cache,
32+
unsigned int pid,
33+
unsigned int cid,
34+
size_t batch) {
35+
return cache.traverseAndEvictItems(pid, cid, batch);
36+
}
37+
38+
static size_t traverseAndPromoteItems(C& cache,
39+
unsigned int pid,
40+
unsigned int cid,
41+
size_t batch) {
42+
return cache.traverseAndPromoteItems(pid, cid, batch);
43+
}
44+
};
45+
46+
enum class MoverDir { Evict = 0, Promote };
47+
48+
// Periodic worker that evicts items from tiers in batches
49+
// The primary aim is to reduce insertion times for new items in the
50+
// cache
51+
template <typename CacheT>
52+
class BackgroundMover : public PeriodicWorker {
53+
public:
54+
using Cache = CacheT;
55+
// @param cache the cache interface
56+
// @param strategy the stragey class that defines how objects are
57+
// moved,
58+
// (promoted vs. evicted and how much)
59+
BackgroundMover(Cache& cache,
60+
std::shared_ptr<BackgroundMoverStrategy> strategy,
61+
MoverDir direction_);
62+
63+
~BackgroundMover() override;
64+
65+
BackgroundMoverStats getStats() const noexcept;
66+
std::map<PoolId, std::map<ClassId, uint64_t>> getClassStats() const noexcept;
67+
68+
void setAssignedMemory(std::vector<MemoryDescriptorType>&& assignedMemory);
69+
70+
private:
71+
std::map<PoolId, std::map<ClassId, uint64_t>> moves_per_class_;
72+
// cache allocator's interface for evicting
73+
using Item = typename Cache::Item;
74+
75+
Cache& cache_;
76+
std::shared_ptr<BackgroundMoverStrategy> strategy_;
77+
MoverDir direction_;
78+
79+
std::function<size_t(Cache&, unsigned int, unsigned int, size_t)> moverFunc;
80+
81+
// implements the actual logic of running the background evictor
82+
void work() override final;
83+
void checkAndRun();
84+
85+
AtomicCounter numMovedItems{0};
86+
AtomicCounter numTraversals{0};
87+
AtomicCounter totalClasses{0};
88+
AtomicCounter totalBytesMoved{0};
89+
90+
std::vector<MemoryDescriptorType> assignedMemory_;
91+
folly::DistributedMutex mutex;
92+
};
93+
} // namespace cachelib
94+
} // namespace facebook
95+
96+
#include "cachelib/allocator/BackgroundMover-inl.h"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) Facebook, Inc. 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 "cachelib/allocator/Cache.h"
20+
21+
namespace facebook {
22+
namespace cachelib {
23+
24+
struct MemoryDescriptorType {
25+
MemoryDescriptorType(PoolId pid, ClassId cid) : pid_(pid), cid_(cid) {}
26+
PoolId pid_;
27+
ClassId cid_;
28+
};
29+
30+
// Base class for background eviction strategy.
31+
class BackgroundMoverStrategy {
32+
public:
33+
virtual std::vector<size_t> calculateBatchSizes(
34+
const CacheBase& cache, std::vector<MemoryDescriptorType> acVec) = 0;
35+
};
36+
37+
} // namespace cachelib
38+
} // namespace facebook

cachelib/allocator/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ add_library (cachelib_allocator
3535
CCacheManager.cpp
3636
ContainerTypes.cpp
3737
FreeMemStrategy.cpp
38+
FreeThresholdStrategy.cpp
3839
HitsPerSlabStrategy.cpp
3940
LruTailAgeStrategy.cpp
4041
MarginalHitsOptimizeStrategy.cpp

0 commit comments

Comments
 (0)