1 #ifndef DASH__MEMORY__SIMPLE_MEMORY_POOL_RESOURCE_H_ 2 #define DASH__MEMORY__SIMPLE_MEMORY_POOL_RESOURCE_H_ 8 #include <dash/Exception.h> 9 #include <dash/Types.h> 11 #include <dash/allocator/AllocatorBase.h> 12 #include <dash/memory/MemorySpace.h> 38 template <
size_t Blocksize>
42 std::uint8_t _data[Blocksize];
55 template <
class LocalMemSpace>
59 typename LocalMemSpace::memory_space_type_category> {
63 static constexpr
const size_t MAX_ALIGN =
alignof(dash::max_align_t);
65 static constexpr
const size_t MAX_BLOCKS_PER_CHUNK = 32;
67 static constexpr
const size_t MAX_BLOCK_SIZE = 16;
71 using Block = detail::Block<MAX_BLOCK_SIZE>;
72 using Chunk = detail::Chunk;
75 memory_traits::is_local::value,
"Upstream Memory Space must be local");
81 using memory_space_domain_category =
87 LocalMemSpace* resource =
nullptr) noexcept;
104 inline LocalMemSpace* upstream_resource();
110 Block* allocateChunk(
std::
size_t nbytes);
113 void* do_allocate(
size_t bytes,
size_t alignment) override;
114 void do_deallocate(
void* p,
size_t bytes,
size_t alignment) override;
115 bool do_is_equal(
std::pmr::memory_resource const& other) const
122 void reserve(
std::
size_t nblocks);
125 Chunk* m_chunklist =
nullptr;
126 Block* m_freelist =
nullptr;
127 int m_blocks_per_chunk;
128 LocalMemSpace* m_resource;
132 template <class LocalMemSpace>
134 LocalMemSpace* r) noexcept
135 : m_chunklist(
nullptr)
136 , m_freelist(
nullptr)
137 , m_blocks_per_chunk(1)
140 : static_cast<LocalMemSpace*>(
148 template <
typename LocalMemSpace>
151 : m_chunklist(
nullptr)
152 , m_freelist(
nullptr)
153 , m_blocks_per_chunk(other.m_blocks_per_chunk)
154 , m_resource(other.m_resource)
159 template <
typename LocalMemSpace>
162 : m_chunklist(other.m_chunklist)
163 , m_freelist(other.m_freelist)
164 , m_blocks_per_chunk(other.m_blocks_per_chunk)
165 , m_resource(other.m_resource)
167 other.m_chunklist =
nullptr;
168 other.m_freelist =
nullptr;
169 other.m_blocks_per_chunk = 1;
171 template <
typename LocalMemSpace>
173 size_t bytes,
size_t alignment)
178 if (bytes > MAX_BLOCK_SIZE) {
179 std::size_t
const header_sz =
sizeof(detail::Header);
181 if (std::size_t(-1) - header_sz < bytes) {
182 throw std::bad_alloc();
185 detail::Header* p =
reinterpret_cast<detail::Header*
>(
186 m_resource->allocate(bytes + header_sz, MAX_ALIGN));
188 p->size = bytes + header_sz;
197 void*
block =
reinterpret_cast<void*
>(m_freelist);
198 m_freelist = m_freelist->next;
202 template <
typename LocalMemSpace>
204 void* address,
size_t bytes,
size_t alignment)
209 if (bytes > MAX_BLOCK_SIZE) {
211 std::size_t
const header_sz =
sizeof(detail::Header);
213 auto header =
static_cast<detail::Header*
>(
214 static_cast<void*
>(
reinterpret_cast<char*
>(address) - header_sz));
216 std::size_t
const sz = header->size;
218 m_resource->deallocate(header, sz, MAX_ALIGN);
221 DASH_ASSERT(address);
222 reinterpret_cast<Block*
>(address)->next = m_freelist;
223 m_freelist =
reinterpret_cast<Block*
>(address);
226 template <
typename LocalMemSpace>
234 return this->m_resource == other_p->m_resource;
239 template <
typename LocalMemSpace>
244 DASH_ASSERT(0 < nblocks);
246 Block*
begin = allocateChunk(nblocks *
sizeof(Block));
247 Block*
end = begin + nblocks - 1;
249 for (Block* p = begin; p <
end; ++p) {
252 end->next = m_freelist;
256 template <
typename LocalMemSpace>
257 inline LocalMemSpace*
263 template <
typename LocalMemSpace>
266 while (m_chunklist) {
267 Chunk* lastChunk = m_chunklist;
268 m_chunklist = m_chunklist->next;
269 m_resource->deallocate(lastChunk, MAX_ALIGN);
274 template <
typename LocalMemSpace>
278 reserve(m_blocks_per_chunk);
281 m_blocks_per_chunk *= 2;
283 if (m_blocks_per_chunk > MAX_BLOCKS_PER_CHUNK)
284 m_blocks_per_chunk = MAX_BLOCKS_PER_CHUNK;
287 template <
typename LocalMemSpace>
288 typename SimpleMemoryPoolResource<LocalMemSpace>::Block*
292 std::size_t numBytes =
sizeof(Chunk) + nbytes;
295 reinterpret_cast<Chunk*
>(m_resource->allocate(numBytes, MAX_ALIGN));
298 chunkPtr->next = m_chunklist;
299 m_chunklist = chunkPtr;
302 return reinterpret_cast<Block*
>(chunkPtr + 1);
305 template <
typename LocalMemSpace>
313 #endif // DASH__MEMORY__SIMPLE_MEMORY_POOL_RESOURCE_H_ MemorySpace< MSpaceDomainCategory, MSpaceTypeCategory > * get_default_memory_space()
Forward declarations.
size_t size()
Return the number of units in the global team.
constexpr auto end(RangeType &&range) -> decltype(std::forward< RangeType >(range).end())
This class is a simple memory pool which holds allocates elements of size ValueType.
constexpr auto begin(RangeType &&range) -> decltype(std::forward< RangeType >(range).begin())
typename MemSpace::memory_space_domain_category memory_space_domain_category
The underlying memory domain (local, global, etc.)
LocalMemSpace * upstream_resource()
Returns the underlying memory resource.
void release()
deallocate all memory blocks of all chunks
typename memory_traits::memory_space_type_category memory_space_type_category
Require for memory traits.
see https://en.cppreference.com/w/cpp/feature_test for recommended feature tests
typename MemSpace::memory_space_type_category memory_space_type_category
The underlying memory type (Host, CUDA, HBW, etc.)
constexpr auto block(OffsetT block_idx, const ViewType &view) -> typename std::enable_if<(!dash::view_traits< ViewType >::is_local::value), ViewBlockMod< ViewType > >::type
Blocks view from global view.