Skip to content

Commit 748babd

Browse files
guptaskbyrnedj
authored andcommitted
This is the additional multi-tier support needed
for the compressed ptr changes that were introduced upstream. - Includes later cosmetic changes added by sounak 9cb5c29
1 parent 5bc9f79 commit 748babd

File tree

7 files changed

+82
-24
lines changed

7 files changed

+82
-24
lines changed

cachelib/allocator/CacheAllocator.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1296,6 +1296,7 @@ class CacheAllocator : public CacheBase {
12961296
sizeof(typename RefcountWithFlags::Value) + sizeof(uint32_t) +
12971297
sizeof(uint32_t) + sizeof(KAllocation)) == sizeof(Item),
12981298
"vtable overhead");
1299+
// Check for CompressedPtr single/multi tier support
12991300
static_assert(32 == sizeof(Item), "item overhead is 32 bytes");
13001301

13011302
// make sure there is no overhead in ChainedItem on top of a regular Item
@@ -1938,7 +1939,7 @@ class CacheAllocator : public CacheBase {
19381939
}
19391940

19401941
typename Item::PtrCompressor createPtrCompressor() const {
1941-
return allocator_[0 /* TODO */]->createPtrCompressor<Item>();
1942+
return typename Item::PtrCompressor(allocator_);
19421943
}
19431944

19441945
// helper utility to throttle and optionally log.

cachelib/allocator/memory/AllocationClass.cpp

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ AllocationClass::AllocationClass(ClassId classId,
5050
poolId_(poolId),
5151
allocationSize_(allocSize),
5252
slabAlloc_(s),
53-
freedAllocations_{slabAlloc_.createPtrCompressor<FreeAlloc>()} {
53+
freedAllocations_{slabAlloc_.createSingleTierPtrCompressor<FreeAlloc>()} {
5454
checkState();
5555
}
5656

@@ -102,7 +102,7 @@ AllocationClass::AllocationClass(
102102
currSlab_(s.getSlabForIdx(*object.currSlabIdx())),
103103
slabAlloc_(s),
104104
freedAllocations_(*object.freedAllocationsObject(),
105-
slabAlloc_.createPtrCompressor<FreeAlloc>()),
105+
slabAlloc_.createSingleTierPtrCompressor<FreeAlloc>()),
106106
canAllocate_(*object.canAllocate()) {
107107
if (!slabAlloc_.isRestorable()) {
108108
throw std::logic_error("The allocation class cannot be restored.");
@@ -356,9 +356,10 @@ std::pair<bool, std::vector<void*>> AllocationClass::pruneFreeAllocs(
356356
// allocated slab, release any freed allocations belonging to this slab.
357357
// Set the bit to true if the corresponding allocation is freed, false
358358
// otherwise.
359-
FreeList freeAllocs{slabAlloc_.createPtrCompressor<FreeAlloc>()};
360-
FreeList notInSlab{slabAlloc_.createPtrCompressor<FreeAlloc>()};
361-
FreeList inSlab{slabAlloc_.createPtrCompressor<FreeAlloc>()};
359+
FreeList freeAllocs{slabAlloc_.createSingleTierPtrCompressor<FreeAlloc>()};
360+
FreeList notInSlab{slabAlloc_.createSingleTierPtrCompressor<FreeAlloc>()};
361+
FreeList inSlab{slabAlloc_.createSingleTierPtrCompressor<FreeAlloc>()};
362+
362363

363364
lock_->lock_combine([&]() {
364365
// Take the allocation class free list offline

cachelib/allocator/memory/AllocationClass.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -445,7 +445,7 @@ class AllocationClass {
445445
struct CACHELIB_PACKED_ATTR FreeAlloc {
446446
using CompressedPtr = facebook::cachelib::CompressedPtr;
447447
using PtrCompressor =
448-
facebook::cachelib::PtrCompressor<FreeAlloc, SlabAllocator>;
448+
facebook::cachelib::SingleTierPtrCompressor<FreeAlloc, SlabAllocator>;
449449
SListHook<FreeAlloc> hook_{};
450450
};
451451

cachelib/allocator/memory/CompressedPtr.h

Lines changed: 64 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,12 @@ namespace cachelib {
2727

2828
class SlabAllocator;
2929

30+
template <typename PtrType, typename AllocatorContainer>
31+
class PtrCompressor;
32+
3033
// This CompressedPtr makes decompression fast by staying away from division and
31-
// modulo arithmetic and doing those during the compression time. We most often
32-
// decompress a CompressedPtr than compress a pointer while creating one. This
34+
// modulo arithmetic and doing those during the compression time. We most often
35+
// decompress a CompressedPtr than compress a pointer while creating one. This
3336
// is used for pointer compression by the memory allocator.
3437

3538
// We compress pointers by storing the tier index, slab index and alloc index of
@@ -38,8 +41,9 @@ class SlabAllocator;
3841
// kNumSlabBits - 6 = 16 bits for storing the alloc index. The tier id occupies
3942
// the 32nd bit only since its value cannot exceed kMaxTiers (2). This leaves
4043
// the remaining (32 - (kNumSlabBits - 6) - 1 bit for tier id) = 15 bits for
41-
// the slab index. Hence we can index 128 GiB of memory per tier in multi-tier
42-
// configuration or index 256 GiB in single-tier configuration.
44+
// the slab index. Hence we can index 128 GiB of memory in slabs per tier and
45+
// index anything more than 64 byte allocations inside the slab using a 32 bit
46+
// representation.
4347
class CACHELIB_PACKED_ATTR CompressedPtr {
4448
public:
4549
using PtrType = uint32_t;
@@ -158,33 +162,83 @@ class CACHELIB_PACKED_ATTR CompressedPtr {
158162
}
159163

160164
friend SlabAllocator;
165+
template <typename CPtrType, typename AllocatorContainer>
166+
friend class PtrCompressor;
161167
};
162168

163169
template <typename PtrType, typename AllocatorT>
164-
class PtrCompressor {
170+
class SingleTierPtrCompressor {
165171
public:
166-
explicit PtrCompressor(const AllocatorT& allocator) noexcept
172+
explicit SingleTierPtrCompressor(const AllocatorT& allocator) noexcept
167173
: allocator_(allocator) {}
168174

169175
const CompressedPtr compress(const PtrType* uncompressed) const {
170-
return allocator_.compress(uncompressed, true);
176+
return allocator_.compress(uncompressed, false);
171177
}
172178

173179
PtrType* unCompress(const CompressedPtr compressed) const {
174-
return static_cast<PtrType*>(allocator_.unCompress(compressed, true));
180+
return static_cast<PtrType*>(allocator_.unCompress(compressed, false));
175181
}
176182

177-
bool operator==(const PtrCompressor& rhs) const noexcept {
183+
bool operator==(const SingleTierPtrCompressor& rhs) const noexcept {
178184
return &allocator_ == &rhs.allocator_;
179185
}
180186

181-
bool operator!=(const PtrCompressor& rhs) const noexcept {
187+
bool operator!=(const SingleTierPtrCompressor& rhs) const noexcept {
182188
return !(*this == rhs);
183189
}
184190

185191
private:
186192
// memory allocator that does the pointer compression.
187193
const AllocatorT& allocator_;
188194
};
195+
196+
template <typename PtrType, typename AllocatorContainer>
197+
class PtrCompressor {
198+
public:
199+
explicit PtrCompressor(const AllocatorContainer& allocators) noexcept
200+
: allocators_(allocators) {}
201+
202+
const CompressedPtr compress(const PtrType* uncompressed) const {
203+
if (uncompressed == nullptr)
204+
return CompressedPtr{};
205+
206+
TierId tid;
207+
for (tid = 0; tid < allocators_.size(); tid++) {
208+
if (allocators_[tid]->isMemoryInAllocator(
209+
static_cast<const void*>(uncompressed)))
210+
break;
211+
}
212+
213+
bool isMultiTiered = allocators_.size() > 1;
214+
auto cptr = allocators_[tid]->compress(uncompressed, isMultiTiered);
215+
if (isMultiTiered) { // config has multiple tiers
216+
cptr.setTierId(tid);
217+
}
218+
return cptr;
219+
}
220+
221+
PtrType* unCompress(const CompressedPtr compressed) const {
222+
if (compressed.isNull()) {
223+
return nullptr;
224+
}
225+
bool isMultiTiered = allocators_.size() > 1;
226+
auto& allocator = *allocators_[compressed.getTierId(isMultiTiered)];
227+
return static_cast<PtrType*>(
228+
allocator.unCompress(compressed, isMultiTiered));
229+
}
230+
231+
bool operator==(const PtrCompressor& rhs) const noexcept {
232+
return &allocators_ == &rhs.allocators_;
233+
}
234+
235+
bool operator!=(const PtrCompressor& rhs) const noexcept {
236+
return !(*this == rhs);
237+
}
238+
239+
private:
240+
// memory allocator that does the pointer compression.
241+
const AllocatorContainer& allocators_;
242+
};
189243
} // namespace cachelib
190244
} // namespace facebook

cachelib/allocator/memory/MemoryAllocator.h

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -516,12 +516,13 @@ class MemoryAllocator {
516516
using CompressedPtr = facebook::cachelib::CompressedPtr;
517517
template <typename PtrType>
518518
using PtrCompressor =
519-
facebook::cachelib::PtrCompressor<PtrType, SlabAllocator>;
520-
519+
facebook::cachelib::PtrCompressor<PtrType,
520+
std::vector<std::unique_ptr<MemoryAllocator>>>;
521+
521522
template <typename PtrType>
522-
PtrCompressor<PtrType> createPtrCompressor() {
523-
return slabAllocator_.createPtrCompressor<PtrType>();
524-
}
523+
using SingleTierPtrCompressor =
524+
facebook::cachelib::PtrCompressor<PtrType,
525+
SlabAllocator>;
525526

526527
// compress a given pointer to a valid allocation made out of this allocator
527528
// through an allocate() or nullptr. Calling this otherwise with invalid

cachelib/allocator/memory/SlabAllocator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -314,8 +314,8 @@ class SlabAllocator {
314314
}
315315

316316
template <typename PtrType>
317-
PtrCompressor<PtrType, SlabAllocator> createPtrCompressor() const {
318-
return PtrCompressor<PtrType, SlabAllocator>(*this);
317+
SingleTierPtrCompressor<PtrType, SlabAllocator> createSingleTierPtrCompressor() const {
318+
return SingleTierPtrCompressor<PtrType, SlabAllocator>(*this);
319319
}
320320

321321
// returns starting address of memory we own.

run_tests.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
# Newline separated list of tests to ignore
44
BLACKLIST="allocator-test-NavySetupTest
5+
allocator-test-NvmCacheTests
56
shm-test-test_page_size"
67

78
if [ "$1" == "long" ]; then

0 commit comments

Comments
 (0)