[Bf-blender-cvs] [d3c5e882b09] functions: Use monotonic allocator instead of more complex ones
Jacques Lucke
noreply at git.blender.org
Thu Jul 4 18:05:57 CEST 2019
Commit: d3c5e882b09f4d5f73d0a09ee9c14d2e2ad2fb81
Author: Jacques Lucke
Date: Thu Jul 4 18:04:58 2019 +0200
Branches: functions
https://developer.blender.org/rBd3c5e882b09f4d5f73d0a09ee9c14d2e2ad2fb81
Use monotonic allocator instead of more complex ones
===================================================================
A source/blender/blenlib/BLI_monotonic_allocator.hpp
M source/blender/blenlib/BLI_multimap.hpp
D source/blender/blenlib/BLI_multipool.hpp
M source/blender/blenlib/CMakeLists.txt
M source/blender/functions/backends/tuple_call/execution_context.hpp
M source/blender/functions/core/data_flow_graph.hpp
M source/blender/functions/core/data_flow_graph_builder.cpp
M source/blender/functions/core/data_flow_graph_builder.hpp
===================================================================
diff --git a/source/blender/blenlib/BLI_monotonic_allocator.hpp b/source/blender/blenlib/BLI_monotonic_allocator.hpp
new file mode 100644
index 00000000000..5672402bdf2
--- /dev/null
+++ b/source/blender/blenlib/BLI_monotonic_allocator.hpp
@@ -0,0 +1,65 @@
+#pragma once
+
+/**
+ * A monotonic allocator is the simplest form of an allocator. It never reuses any memory, and
+ * therefore does not need a deallocation method. It simply hands out consecutive buffers of
+ * memory. When the current buffer is full, it reallocates a new larger buffer and continues.
+ *
+ * It optionally supports small object optimization. So e.g. when in total less then 20 bytes are
+ * allocated, no actual allocation will be performed.
+ */
+
+#include "BLI_small_vector.hpp"
+
+namespace BLI {
+
+template<uint N = 0> class MonotonicAllocator {
+ private:
+ char m_small_buffer[N];
+ SmallVector<void *> m_pointers;
+
+ void *m_current_buffer;
+ uint m_remaining_capacity;
+ uint m_next_min_alloc_size;
+
+ public:
+ MonotonicAllocator()
+ : m_current_buffer((void *)m_small_buffer),
+ m_remaining_capacity(N),
+ m_next_min_alloc_size(N * 2)
+ {
+ }
+
+ MonotonicAllocator(MonotonicAllocator &other) = delete;
+ MonotonicAllocator(MonotonicAllocator &&other) = delete;
+
+ ~MonotonicAllocator()
+ {
+ for (void *ptr : m_pointers) {
+ MEM_freeN(ptr);
+ }
+ }
+
+ void *allocate(uint size)
+ {
+ if (size <= m_remaining_capacity) {
+ void *ptr = m_current_buffer;
+ m_remaining_capacity -= size;
+ m_current_buffer = POINTER_OFFSET(ptr, size);
+ return ptr;
+ }
+ else {
+ uint byte_size = std::max(m_next_min_alloc_size, size);
+ void *ptr = MEM_mallocN(byte_size, __func__);
+ m_pointers.append(ptr);
+
+ m_current_buffer = POINTER_OFFSET(ptr, size);
+ m_next_min_alloc_size = byte_size * 2;
+ m_remaining_capacity = byte_size - size;
+
+ return ptr;
+ }
+ }
+};
+
+} // namespace BLI
diff --git a/source/blender/blenlib/BLI_multimap.hpp b/source/blender/blenlib/BLI_multimap.hpp
index 33e651e70ef..d8d2b01da03 100644
--- a/source/blender/blenlib/BLI_multimap.hpp
+++ b/source/blender/blenlib/BLI_multimap.hpp
@@ -3,7 +3,6 @@
/* A multimap is a map that allows storing multiple values per key. */
#include "BLI_small_map.hpp"
-#include "BLI_multipool.hpp"
#include "BLI_array_ref.hpp"
namespace BLI {
diff --git a/source/blender/blenlib/BLI_multipool.hpp b/source/blender/blenlib/BLI_multipool.hpp
deleted file mode 100644
index d11fc0bddbf..00000000000
--- a/source/blender/blenlib/BLI_multipool.hpp
+++ /dev/null
@@ -1,70 +0,0 @@
-#pragma once
-
-/* This is similar to a normal MemPool, but supports
- * allocating different sizes. It should only be used
- * when the amount of different sizes is expected to
- * be very small.
- *
- * It is not thread-safe, so only a single thread should
- * allocate memory using this pool at the same time.
- */
-
-#include "BLI_small_map.hpp"
-#include "BLI_mempool.hpp"
-
-namespace BLI {
-
-class MemMultiPool {
- private:
- SmallMap<uint, MemPool *> m_pools;
-
- public:
- MemMultiPool() = default;
- MemMultiPool(MemMultiPool &other) = delete;
-
- ~MemMultiPool()
- {
- for (MemPool *pool : m_pools.values()) {
- delete pool;
- }
- }
-
- template<typename T> T *allocate()
- {
- return (T *)this->allocate(sizeof(T));
- }
-
- template<typename T> T *allocate_array(uint length)
- {
- return (T *)this->allocate(sizeof(T) * length);
- }
-
- void *allocate(uint size)
- {
- uint alloc_size = size + sizeof(uint);
- MemPool *pool = m_pools.lookup_default(alloc_size, NULL);
-
- if (pool == NULL) {
- pool = new MemPool(alloc_size);
- m_pools.add(alloc_size, pool);
- }
-
- void *real_ptr = pool->allocate();
- *(uint *)real_ptr = alloc_size;
-
- void *ptr = (void *)((uint *)real_ptr + 1);
- return ptr;
- }
-
- void deallocate(void *ptr)
- {
- void *real_ptr = (uint *)ptr - 1;
- uint alloc_size = *(uint *)real_ptr;
- BLI_assert(m_pools.contains(alloc_size));
-
- MemPool *pool = m_pools.lookup(alloc_size);
- pool->deallocate(real_ptr);
- }
-};
-
-} /* namespace BLI */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index 95f703357b0..5ac30e82977 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -238,14 +238,15 @@ set(SRC
BLI_array_ref.hpp
BLI_chained_strings.hpp
BLI_composition.hpp
+ BLI_fixed_array_allocator.hpp
BLI_lazy_init.h
BLI_lazy_init.hpp
intern/BLI_lazy_init.cpp
BLI_listbase_wrapper.hpp
BLI_math.hpp
BLI_mempool.hpp
+ BLI_monotonic_allocator.hpp
BLI_multimap.hpp
- BLI_multipool.hpp
BLI_object_pool.hpp
BLI_optional.hpp
BLI_range.hpp
diff --git a/source/blender/functions/backends/tuple_call/execution_context.hpp b/source/blender/functions/backends/tuple_call/execution_context.hpp
index c59e193caf4..b966364945e 100644
--- a/source/blender/functions/backends/tuple_call/execution_context.hpp
+++ b/source/blender/functions/backends/tuple_call/execution_context.hpp
@@ -12,9 +12,12 @@
*/
#include "FN_core.hpp"
+#include "BLI_small_stack.hpp"
namespace FN {
+using BLI::SmallStack;
+
class StackFrame {
public:
virtual std::string to_string() const = 0;
diff --git a/source/blender/functions/core/data_flow_graph.hpp b/source/blender/functions/core/data_flow_graph.hpp
index 9942315aeb1..e0edabb3781 100644
--- a/source/blender/functions/core/data_flow_graph.hpp
+++ b/source/blender/functions/core/data_flow_graph.hpp
@@ -182,7 +182,7 @@ class DataFlowGraph : public RefCountedBase {
SmallVector<InputSocket> m_inputs;
SmallVector<OutputSocket> m_outputs;
SmallVector<uint> m_targets;
- std::unique_ptr<MemMultiPool> m_source_info_pool;
+ std::unique_ptr<MonotonicAllocator<>> m_source_info_pool;
public:
DataFlowGraph() = default;
diff --git a/source/blender/functions/core/data_flow_graph_builder.cpp b/source/blender/functions/core/data_flow_graph_builder.cpp
index aba442a4eb7..98f34bb9382 100644
--- a/source/blender/functions/core/data_flow_graph_builder.cpp
+++ b/source/blender/functions/core/data_flow_graph_builder.cpp
@@ -22,9 +22,9 @@ const StringRefNull DFGB_Socket::name() const
}
}
-DataFlowGraphBuilder::DataFlowGraphBuilder() : m_node_pool(sizeof(DFGB_Node))
+DataFlowGraphBuilder::DataFlowGraphBuilder()
{
- m_source_info_pool = std::unique_ptr<MemMultiPool>(new MemMultiPool());
+ m_source_info_pool = std::unique_ptr<MonotonicAllocator<>>(new MonotonicAllocator<>());
}
DataFlowGraphBuilder::~DataFlowGraphBuilder()
@@ -45,7 +45,7 @@ DataFlowGraphBuilder::~DataFlowGraphBuilder()
DFGB_Node *DataFlowGraphBuilder::insert_function(SharedFunction &fn, SourceInfo *source)
{
BLI_assert(this->is_mutable());
- void *ptr = m_node_pool.allocate();
+ void *ptr = m_node_pool.allocate(sizeof(DFGB_Node));
DFGB_Node *node = new (ptr) DFGB_Node(*this, fn, source);
m_nodes.add_new(node);
return node;
diff --git a/source/blender/functions/core/data_flow_graph_builder.hpp b/source/blender/functions/core/data_flow_graph_builder.hpp
index 7a999973fd2..1829a10236a 100644
--- a/source/blender/functions/core/data_flow_graph_builder.hpp
+++ b/source/blender/functions/core/data_flow_graph_builder.hpp
@@ -12,7 +12,7 @@
#include "BLI_optional.hpp"
#include "BLI_small_set_vector.hpp"
-#include "BLI_multipool.hpp"
+#include "BLI_monotonic_allocator.hpp"
#include "BLI_multimap.hpp"
namespace FN {
@@ -191,8 +191,8 @@ class DataFlowGraphBuilder {
SmallSet<DFGB_Node *> m_nodes;
SmallMap<DFGB_Socket, DFGB_Socket> m_input_origins;
SmallMultiMap<DFGB_Socket, DFGB_Socket> m_output_targets;
- MemPool m_node_pool;
- std::unique_ptr<MemMultiPool> m_source_info_pool;
+ MonotonicAllocator<sizeof(DFGB_Node) * 4> m_node_pool;
+ std::unique_ptr<MonotonicAllocator<>> m_source_info_pool;
friend DFGB_Socket;
friend DataFlowGraph;
More information about the Bf-blender-cvs
mailing list