Skip to content

Commit df1a2a9

Browse files
committed
changed compressed ptr to 32 bits and slab indx size to 15 bits
1 parent 1d16e1a commit df1a2a9

File tree

5 files changed

+94
-68
lines changed

5 files changed

+94
-68
lines changed

cachelib/allocator/Cache.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,9 @@ class CacheBase {
8383
CacheBase(CacheBase&&) = default;
8484
CacheBase& operator=(CacheBase&&) = default;
8585

86-
// TODO: come up with some reasonable number
87-
static constexpr unsigned kMaxTiers = 8;
86+
// Setting max tier count to 2
87+
// This is needed to keep CompressedPtr at 32 bits
88+
static constexpr unsigned kMaxTiers = 2;
8889

8990
// Get a string referring to the cache name for this cache
9091
virtual const std::string getCacheName() const = 0;

cachelib/allocator/memory/AllocationClass.cpp

Lines changed: 5 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_.createSingleTierPtrCompressor<FreeAlloc>()} {
53+
freedAllocations_{slabAlloc_.createPtrCompressor<FreeAlloc>()} {
5454
checkState();
5555
}
5656

@@ -102,7 +102,7 @@ AllocationClass::AllocationClass(
102102
currSlab_(s.getSlabForIdx(*object.currSlabIdx_ref())),
103103
slabAlloc_(s),
104104
freedAllocations_(*object.freedAllocationsObject_ref(),
105-
slabAlloc_.createSingleTierPtrCompressor<FreeAlloc>()),
105+
slabAlloc_.createPtrCompressor<FreeAlloc>()),
106106
canAllocate_(*object.canAllocate_ref()) {
107107
if (!slabAlloc_.isRestorable()) {
108108
throw std::logic_error("The allocation class cannot be restored.");
@@ -356,9 +356,9 @@ 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_.createSingleTierPtrCompressor<FreeAlloc>()};
360-
FreeList notInSlab{slabAlloc_.createSingleTierPtrCompressor<FreeAlloc>()};
361-
FreeList inSlab{slabAlloc_.createSingleTierPtrCompressor<FreeAlloc>()};
359+
FreeList freeAllocs{slabAlloc_.createPtrCompressor<FreeAlloc>()};
360+
FreeList notInSlab{slabAlloc_.createPtrCompressor<FreeAlloc>()};
361+
FreeList inSlab{slabAlloc_.createPtrCompressor<FreeAlloc>()};
362362

363363
lock_->lock_combine([&]() {
364364
// 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
@@ -446,7 +446,7 @@ class AllocationClass {
446446
struct CACHELIB_PACKED_ATTR FreeAlloc {
447447
using CompressedPtr = facebook::cachelib::CompressedPtr;
448448
using PtrCompressor =
449-
facebook::cachelib::SingleTierPtrCompressor<FreeAlloc, SlabAllocator>;
449+
facebook::cachelib::PtrCompressor<FreeAlloc, SlabAllocator>;
450450
SListHook<FreeAlloc> hook_{};
451451
};
452452

cachelib/allocator/memory/CompressedPtr.h

Lines changed: 83 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,51 @@
1717
#pragma once
1818

1919
#include <folly/logging/xlog.h>
20-
2120
#include <memory>
22-
2321
#include "cachelib/allocator/memory/Slab.h"
2422

23+
#include <deque>
24+
#include <forward_list>
25+
#include <list>
26+
#include <map>
27+
#include <queue>
28+
#include <set>
29+
#include <stack>
30+
#include <string>
31+
#include <tuple>
32+
#include <type_traits>
33+
#include <unordered_map>
34+
#include <unordered_set>
35+
#include <utility>
36+
#include <vector>
37+
#include <type_traits>
38+
39+
//specialize a type for all of the STL containers.
40+
namespace IsContainerImpl{
41+
template <typename T> struct IsContainer:std::false_type{};
42+
template <typename T, std::size_t N> struct IsContainer<std::array<T,N>>:std::true_type{};
43+
template <typename... Args> struct IsContainer<std::vector<Args...>>:std::true_type{};
44+
template <typename... Args> struct IsContainer<std::deque<Args...>>:std::true_type{};
45+
template <typename... Args> struct IsContainer<std::list<Args...>>:std::true_type{};
46+
template <typename... Args> struct IsContainer<std::forward_list<Args...>>:std::true_type{};
47+
template <typename... Args> struct IsContainer<std::set<Args...>>:std::true_type{};
48+
template <typename... Args> struct IsContainer<std::multiset<Args...>>:std::true_type{};
49+
template <typename... Args> struct IsContainer<std::map<Args...>>:std::true_type{};
50+
template <typename... Args> struct IsContainer<std::multimap<Args...>>:std::true_type{};
51+
template <typename... Args> struct IsContainer<std::unordered_set<Args...>>:std::true_type{};
52+
template <typename... Args> struct IsContainer<std::unordered_multiset<Args...>>:std::true_type{};
53+
template <typename... Args> struct IsContainer<std::unordered_map<Args...>>:std::true_type{};
54+
template <typename... Args> struct IsContainer<std::unordered_multimap<Args...>>:std::true_type{};
55+
template <typename... Args> struct IsContainer<std::stack<Args...>>:std::true_type{};
56+
template <typename... Args> struct IsContainer<std::queue<Args...>>:std::true_type{};
57+
template <typename... Args> struct IsContainer<std::priority_queue<Args...>>:std::true_type{};
58+
}
59+
60+
//type trait to utilize the implementation type traits as well as decay the type
61+
template <typename T> struct IsContainer {
62+
static constexpr bool const value = IsContainerImpl::IsContainer<std::decay_t<T>>::value;
63+
};
64+
2565
namespace facebook {
2666
namespace cachelib {
2767

@@ -31,20 +71,22 @@ template <typename PtrType, typename AllocatorContainer>
3171
class PtrCompressor;
3272

3373
// the following are for pointer compression for the memory allocator. We
34-
// compress pointers by storing the slab index and the alloc index of the
35-
// allocation inside the slab. With slab worth kNumSlabBits of data, if we
36-
// have the min allocation size as 64 bytes, that requires kNumSlabBits - 6
37-
// bits for storing the alloc index. This leaves the remaining (32 -
38-
// (kNumSlabBits - 6)) bits for the slab index. Hence we can index 256 GiB
39-
// of memory in slabs and index anything more than 64 byte allocations inside
40-
// the slab using a 32 bit representation.
74+
// compress pointers by storing the tier index, slab index and alloc index
75+
// of the allocation inside the slab. With slab worth kNumSlabBits (22 bits)
76+
// of data, if we have the min allocation size as 64 bytes, that requires
77+
// kNumSlabBits - 6 = 16 bits for storing the alloc index. The tier id
78+
// occupies the 32nd bit only since its value cannot exceed kMaxTiers (2).
79+
// This leaves the remaining (32 -(kNumSlabBits - 6) - 1 bit for tier id) =
80+
// 15 bits for the slab index. Hence we can index 128 GiB of memory in slabs
81+
// per tier and index anything more than 64 byte allocations inside the slab
82+
// using a 32 bit representation.
4183
//
4284
// This CompressedPtr makes decompression fast by staying away from division and
4385
// modulo arithmetic and doing those during the compression time. We most often
4486
// decompress a CompressedPtr than compress a pointer while creating one.
4587
class CACHELIB_PACKED_ATTR CompressedPtr {
4688
public:
47-
using PtrType = uint64_t;
89+
using PtrType = uint32_t;
4890
// Thrift doesn't support unsigned type
4991
using SerializedPtrType = int64_t;
5092

@@ -103,26 +145,28 @@ class CACHELIB_PACKED_ATTR CompressedPtr {
103145
static constexpr unsigned int kNumAllocIdxBits =
104146
Slab::kNumSlabBits - Slab::kMinAllocPower;
105147

106-
// Use topmost 32 bits for TierId
107-
// XXX: optimize
108-
static constexpr unsigned int kNumTierIdxOffset = 32;
148+
// Use the top bit for tier id
149+
static constexpr unsigned int kNumTierIdxOffset = 31;
109150

110151
static constexpr PtrType kAllocIdxMask = ((PtrType)1 << kNumAllocIdxBits) - 1;
111152

112153
// kNumTierIdxBits most significant bits
113-
static constexpr PtrType kTierIdxMask = (((PtrType)1 << kNumTierIdxOffset) - 1) << (NumBits<PtrType>::value - kNumTierIdxOffset);
154+
static constexpr PtrType kTierIdxMask = (PtrType)1 << kNumTierIdxOffset;
114155

115-
// Number of bits for the slab index. This will be the top 16 bits of the
156+
// Number of bits for the slab index. This will be the 16th - 31st bits of the
116157
// compressed ptr.
117158
static constexpr unsigned int kNumSlabIdxBits =
118-
NumBits<PtrType>::value - kNumTierIdxOffset - kNumAllocIdxBits;
159+
kNumTierIdxOffset - kNumAllocIdxBits;
119160

120161
// Compress the given slabIdx and allocIdx into a 64-bit compressed
121162
// pointer.
122-
static PtrType compress(uint32_t slabIdx, uint32_t allocIdx, TierId tid) noexcept {
163+
static PtrType compress(uint32_t slabIdx,
164+
uint32_t allocIdx,
165+
TierId tid) noexcept {
123166
XDCHECK_LE(allocIdx, kAllocIdxMask);
124167
XDCHECK_LT(slabIdx, (1u << kNumSlabIdxBits) - 1);
125-
return (static_cast<uint64_t>(tid) << kNumTierIdxOffset) + (slabIdx << kNumAllocIdxBits) + allocIdx;
168+
return (static_cast<uint64_t>(tid) << kNumTierIdxOffset) +
169+
(slabIdx << kNumAllocIdxBits) + allocIdx;
126170
}
127171

128172
// Get the slab index of the compressed ptr
@@ -153,62 +197,43 @@ class CACHELIB_PACKED_ATTR CompressedPtr {
153197
friend class PtrCompressor;
154198
};
155199

156-
template <typename PtrType, typename AllocatorT>
157-
class SingleTierPtrCompressor {
158-
public:
159-
explicit SingleTierPtrCompressor(const AllocatorT& allocator) noexcept
160-
: allocator_(allocator) {}
161-
162-
const CompressedPtr compress(const PtrType* uncompressed) const {
163-
return allocator_.compress(uncompressed);
164-
}
165-
166-
PtrType* unCompress(const CompressedPtr compressed) const {
167-
return static_cast<PtrType*>(allocator_.unCompress(compressed));
168-
}
169-
170-
bool operator==(const SingleTierPtrCompressor& rhs) const noexcept {
171-
return &allocator_ == &rhs.allocator_;
172-
}
173-
174-
bool operator!=(const SingleTierPtrCompressor& rhs) const noexcept {
175-
return !(*this == rhs);
176-
}
177-
178-
private:
179-
// memory allocator that does the pointer compression.
180-
const AllocatorT& allocator_;
181-
};
182-
183200
template <typename PtrType, typename AllocatorContainer>
184201
class PtrCompressor {
185202
public:
186203
explicit PtrCompressor(const AllocatorContainer& allocators) noexcept
187204
: allocators_(allocators) {}
188205

189206
const CompressedPtr compress(const PtrType* uncompressed) const {
190-
if (uncompressed == nullptr)
207+
if (uncompressed == nullptr) {
191208
return CompressedPtr{};
192-
193-
TierId tid;
194-
for (tid = 0; tid < allocators_.size(); tid++) {
195-
if (allocators_[tid]->isMemoryInAllocator(static_cast<const void*>(uncompressed)))
196-
break;
197209
}
198-
199-
auto cptr = allocators_[tid]->compress(uncompressed);
200-
cptr.setTierId(tid);
201-
202-
return cptr;
210+
if (IsContainer<decltype(allocators_)>::value) {
211+
TierId tid;
212+
for (tid = 0; tid < allocators_.size(); tid++) {
213+
if (allocators_[tid]->isMemoryInAllocator(
214+
static_cast<const void*>(uncompressed)))
215+
break;
216+
}
217+
auto cptr = allocators_[tid]->compress(uncompressed);
218+
cptr.setTierId(tid);
219+
return cptr;
220+
221+
} else {
222+
return allocators_.compress(uncompressed);
223+
}
203224
}
204225

205226
PtrType* unCompress(const CompressedPtr compressed) const {
206227
if (compressed.isNull()) {
207228
return nullptr;
208229
}
230+
if (IsContainer<decltype(allocators_)>::value) {
231+
auto& allocator = *allocators_[compressed.getTierId()];
232+
return static_cast<PtrType*>(allocator.unCompress(compressed));
209233

210-
auto &allocator = *allocators_[compressed.getTierId()];
211-
return static_cast<PtrType*>(allocator.unCompress(compressed));
234+
} else {
235+
return static_cast<PtrType*>(allocators_.unCompress(compressed));
236+
}
212237
}
213238

214239
bool operator==(const PtrCompressor& rhs) const noexcept {

cachelib/allocator/memory/SlabAllocator.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -308,8 +308,8 @@ class SlabAllocator {
308308
}
309309

310310
template <typename PtrType>
311-
SingleTierPtrCompressor<PtrType, SlabAllocator> createSingleTierPtrCompressor() const {
312-
return SingleTierPtrCompressor<PtrType, SlabAllocator>(*this);
311+
PtrCompressor<PtrType, SlabAllocator> createPtrCompressor() const {
312+
return PtrCompressor<PtrType, SlabAllocator>(*this);
313313
}
314314

315315
// returns starting address of memory we own.

0 commit comments

Comments
 (0)