[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