[Bf-blender-cvs] [3ad9ccaba7e] functions: initial array allocator

Jacques Lucke noreply at git.blender.org
Mon Jan 27 22:09:43 CET 2020


Commit: 3ad9ccaba7e06830c6b3ccf862b65e671a312209
Author: Jacques Lucke
Date:   Thu Jan 23 15:15:29 2020 +0100
Branches: functions
https://developer.blender.org/rB3ad9ccaba7e06830c6b3ccf862b65e671a312209

initial array allocator

===================================================================

A	source/blender/blenlib/BLI_array_allocator.h
M	source/blender/blenlib/CMakeLists.txt
M	source/blender/functions/intern/multi_functions/network.cc

===================================================================

diff --git a/source/blender/blenlib/BLI_array_allocator.h b/source/blender/blenlib/BLI_array_allocator.h
new file mode 100644
index 00000000000..8393a9125d5
--- /dev/null
+++ b/source/blender/blenlib/BLI_array_allocator.h
@@ -0,0 +1,101 @@
+#ifndef __BLI_ARRAY_ALLOCATOR_H__
+#define __BLI_ARRAY_ALLOCATOR_H__
+
+#include "BLI_vector.h"
+#include "BLI_stack_cxx.h"
+#include "BLI_map.h"
+#include "BLI_utility_mixins.h"
+
+namespace BLI {
+
+class ArrayAllocator : NonCopyable, NonMovable {
+ private:
+  uint m_array_size;
+
+  Vector<Stack<void *>, 16> m_buffers;
+  Vector<void *, 16> m_all_buffers;
+
+#ifdef DEBUG
+  Map<void *, uint> m_element_size_by_buffer;
+#endif
+
+ public:
+  ArrayAllocator(uint array_size) : m_array_size(array_size)
+  {
+  }
+
+  ~ArrayAllocator()
+  {
+#ifdef DEBUG
+    uint buffer_count = 0;
+    for (Stack<void *> &stack : m_buffers) {
+      buffer_count += stack.size();
+    }
+    /* Make sure all arrays have been deallocated before the allocator is destructed. */
+    BLI_assert(m_all_buffers.size() == buffer_count);
+#endif
+
+    for (void *buffer : m_all_buffers) {
+      MEM_freeN(buffer);
+    }
+  }
+
+  uint array_size() const
+  {
+    return m_array_size;
+  }
+
+  void *allocate(uint element_size, uint alignment)
+  {
+    BLI_assert(alignment <= 64);
+    UNUSED_VARS_NDEBUG(alignment);
+
+    std::cout << "Allocate array - Length: " << m_array_size << "  Element Size: " << element_size
+              << "\n";
+
+    Stack<void *> &stack = this->stack_for_element_size(element_size);
+    if (stack.is_empty()) {
+      void *new_buffer = MEM_mallocN_aligned(
+          m_array_size * element_size, 64, "allocate in ArrayAllocator");
+      m_all_buffers.append(new_buffer);
+      stack.push(new_buffer);
+#ifdef DEBUG
+      m_element_size_by_buffer.add_new(new_buffer, element_size);
+#endif
+    }
+
+    return stack.pop();
+  }
+
+  void deallocate(uint element_size, void *buffer)
+  {
+#ifdef DEBUG
+    uint actual_element_size = m_element_size_by_buffer.lookup(buffer);
+    BLI_assert(element_size == actual_element_size);
+#endif
+
+    Stack<void *> &stack = this->stack_for_element_size(element_size);
+    BLI_assert(!stack.contains(buffer));
+    stack.push(buffer);
+  }
+
+  template<typename T> MutableArrayRef<T> allocate()
+  {
+    T *buffer = (T *)this->allocate(sizeof(T), alignof(T));
+    return MutableArrayRef<T>(buffer, m_array_size);
+  }
+
+ private:
+  Stack<void *> &stack_for_element_size(uint element_size)
+  {
+    if (UNLIKELY(element_size > m_buffers.size())) {
+      uint missing_amount = element_size - m_buffers.size();
+      m_buffers.append_n_times({}, missing_amount);
+    }
+    return m_buffers[element_size - 1];
+  }
+};
+
+}  // namespace BLI
+
+#endif /* __BLI_ARRAY_ALLOCATOR_H__ */
diff --git a/source/blender/blenlib/CMakeLists.txt b/source/blender/blenlib/CMakeLists.txt
index bafd0b8bf41..efe7c6f8c8a 100644
--- a/source/blender/blenlib/CMakeLists.txt
+++ b/source/blender/blenlib/CMakeLists.txt
@@ -278,6 +278,7 @@ set(SRC
   BLI_string_multi_map.h
   BLI_index_to_ref_map.h
   BLI_rand_cxx.h
+  BLI_array_allocator.h
 )
 
 set(LIB
diff --git a/source/blender/functions/intern/multi_functions/network.cc b/source/blender/functions/intern/multi_functions/network.cc
index cf5c9e9c8ef..8f337f4ad16 100644
--- a/source/blender/functions/intern/multi_functions/network.cc
+++ b/source/blender/functions/intern/multi_functions/network.cc
@@ -1,11 +1,16 @@
 #include "network.h"
 
+#include "BLI_array_allocator.h"
+
 namespace FN {
 
+using BLI::ArrayAllocator;
+
 class MF_EvaluateNetwork_Storage {
  private:
   MonotonicAllocator<256> m_single_allocator;
   IndexMask m_mask;
+  ArrayAllocator &m_array_allocator;
   Vector<GenericVectorArray *> m_vector_arrays;
   Vector<GenericMutableArrayRef> m_arrays;
   Vector<GenericMutableArrayRef> m_single_element_arrays;
@@ -15,8 +20,10 @@ class MF_EvaluateNetwork_Storage {
   Map<uint, GenericMutableArrayRef> m_array_ref_for_inputs;
 
  public:
-  MF_EvaluateNetwork_Storage(IndexMask mask) : m_mask(mask)
+  MF_EvaluateNetwork_Storage(IndexMask mask, ArrayAllocator &array_allocator)
+      : m_mask(mask), m_array_allocator(array_allocator)
   {
+    BLI_assert(array_allocator.array_size() >= mask.min_array_size());
   }
 
   ~MF_EvaluateNetwork_Storage()
@@ -26,7 +33,7 @@ class MF_EvaluateNetwork_Storage {
     }
     for (GenericMutableArrayRef array : m_arrays) {
       array.destruct_indices(m_mask);
-      MEM_freeN(array.buffer());
+      m_array_allocator.deallocate(array.type().size(), array.buffer());
     }
     for (GenericMutableArrayRef array : m_single_element_arrays) {
       array.destruct_indices(IndexMask(1));
@@ -41,7 +48,7 @@ class MF_EvaluateNetwork_Storage {
   GenericMutableArrayRef allocate_array(const CPPType &type)
   {
     uint size = m_mask.min_array_size();
-    void *buffer = MEM_malloc_arrayN(size, type.size(), __func__);
+    void *buffer = m_array_allocator.allocate(type.size(), type.alignment());
     GenericMutableArrayRef array(type, buffer, size);
     m_arrays.append(array);
     return array;
@@ -244,7 +251,9 @@ void MF_EvaluateNetwork::call(IndexMask mask, MFParams params, MFContext context
     return;
   }
 
-  Storage storage(mask);
+  ArrayAllocator array_allocator(mask.min_array_size());
+
+  Storage storage(mask, array_allocator);
   this->copy_inputs_to_storage(params, storage);
   this->evaluate_network_to_compute_outputs(context, storage);
   this->copy_computed_values_to_outputs(params, storage);



More information about the Bf-blender-cvs mailing list