summaryrefslogtreecommitdiffstatshomepage
path: root/src/lib/netlist/plib/pmempool.h
diff options
context:
space:
mode:
author couriersud <couriersud@gmx.org>2019-02-21 22:59:17 +0100
committer couriersud <couriersud@gmx.org>2019-02-22 08:18:01 +0100
commitcf73ccc764d574284bef4ce95ee5bc3e9089f053 (patch)
tree1655c2836b200c90d5fe5dd5833159e7e8be1522 /src/lib/netlist/plib/pmempool.h
parent6ed352261d40e37887357fe901dc380d6ef79844 (diff)
netlist: memory management. [Couriersud]
Memory management in plib is now alignment-aware. All allocations respect c++11 alignas. Selected classes like parray and aligned_vector also provide hints (__builtin_assume_aligned) to g++ and clang. The alignment optimizations have little impact on the current use cases. They only become effective on bigger data processing. What has a measurable impact is memory pooling. This speeds up netlist games like breakout and pong by about 5%. Tested with linux, macosx and windows cross builds. All features are disabled since I can not rule out they may temporarily break more exotic builds.
Diffstat (limited to 'src/lib/netlist/plib/pmempool.h')
-rw-r--r--src/lib/netlist/plib/pmempool.h45
1 files changed, 30 insertions, 15 deletions
diff --git a/src/lib/netlist/plib/pmempool.h b/src/lib/netlist/plib/pmempool.h
index 80e30ada324..c55d66d8847 100644
--- a/src/lib/netlist/plib/pmempool.h
+++ b/src/lib/netlist/plib/pmempool.h
@@ -34,7 +34,6 @@ namespace plib {
void operator()(T *p) const
{
- p->~T();
P::free(p);
}
};
@@ -83,7 +82,7 @@ namespace plib {
block * new_block(std::size_t min_bytes)
{
- auto *b = new block(this, min_bytes);
+ auto *b = plib::pnew<block>(this, min_bytes);
m_blocks.push_back(b);
return b;
}
@@ -123,22 +122,27 @@ namespace plib {
}
}
- void *alloc(size_t size, size_t align)
+ template <std::size_t ALIGN>
+ void *alloc(size_t size)
{
+ size_t align = ALIGN;
if (align < m_min_align)
align = m_min_align;
- size_t rs = (size + align - 1) & ~(align - 1);
+ size_t rs = size + align;
for (auto &b : m_blocks)
{
if (b->m_free > rs)
{
b->m_free -= rs;
b->m_num_alloc++;
- auto ret = reinterpret_cast<void *>(b->m_data + b->m_cur);
+ auto *ret = reinterpret_cast<void *>(b->m_data + b->m_cur);
auto capacity(rs);
- std::align(align, size, ret, capacity);
+ ret = std::align(align, size, ret, capacity);
+ if (ret == nullptr)
+ printf("Oh no\n");
sinfo().insert({ ret, info(b, b->m_cur)});
+ rs -= (capacity - size);
b->m_cur += rs;
return ret;
@@ -148,17 +152,24 @@ namespace plib {
block *b = new_block(rs);
b->m_num_alloc = 1;
b->m_free = m_min_alloc - rs;
- auto ret = reinterpret_cast<void *>(b->m_data + b->m_cur);
+ auto *ret = reinterpret_cast<void *>(b->m_data + b->m_cur);
auto capacity(rs);
- std::align(align, size, ret, capacity);
+ ret = std::align(align, size, ret, capacity);
+ if (ret == nullptr)
+ printf("Oh no\n");
sinfo().insert({ ret, info(b, b->m_cur)});
+ rs -= (capacity - size);
b->m_cur += rs;
return ret;
}
}
- static void free(void *ptr)
+ template <typename T>
+ static void free(T *ptr)
{
+ /* call destructor */
+ ptr->~T();
+
auto it = sinfo().find(ptr);
if (it == sinfo().end())
plib::terminate("mempool::free - pointer not found\n");
@@ -182,7 +193,7 @@ namespace plib {
template<typename T, typename... Args>
poolptr<T> make_poolptr(Args&&... args)
{
- auto mem = this->alloc(sizeof(T), alignof(T));
+ auto *mem = this->alloc<alignof(T)>(sizeof(T));
auto *obj = new (mem) T(std::forward<Args>(args)...);
poolptr<T> a(obj, true);
return std::move(a);
@@ -208,6 +219,7 @@ namespace plib {
~mempool_default() = default;
+#if 0
void *alloc(size_t size)
{
plib::unused_var(m_min_alloc); // -Wunused-private-field fires without
@@ -216,9 +228,11 @@ namespace plib {
return ::operator new(size);
}
- static void free(void *ptr)
+#endif
+ template <typename T>
+ static void free(T *ptr)
{
- ::operator delete(ptr);
+ plib::pdelete(ptr);
}
template <typename T>
@@ -227,12 +241,13 @@ namespace plib {
template<typename T, typename... Args>
poolptr<T> make_poolptr(Args&&... args)
{
- auto mem(alloc(sizeof(T)));
- auto *obj = new (mem) T(std::forward<Args>(args)...);
+ plib::unused_var(m_min_alloc); // -Wunused-private-field fires without
+ plib::unused_var(m_min_align);
+
+ auto *obj = plib::pnew<T>(std::forward<Args>(args)...);
poolptr<T> a(obj, true);
return std::move(a);
}
-
};