[Bf-blender-cvs] [9880bebd1a9] functions: improve linear allocator

Jacques Lucke noreply at git.blender.org
Mon Feb 10 12:26:32 CET 2020


Commit: 9880bebd1a9a6262b16635bfeb7b003ea3ec0a9b
Author: Jacques Lucke
Date:   Mon Feb 10 11:47:17 2020 +0100
Branches: functions
https://developer.blender.org/rB9880bebd1a9a6262b16635bfeb7b003ea3ec0a9b

improve linear allocator

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

M	source/blender/blenlib/BLI_linear_allocator.h
M	source/blender/blenlib/BLI_multi_map.h
M	source/blender/functions/FN_attributes_ref.h
M	source/blender/functions/intern/multi_functions/network.cc
M	tests/gtests/blenlib/BLI_linear_allocator_test.cc

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

diff --git a/source/blender/blenlib/BLI_linear_allocator.h b/source/blender/blenlib/BLI_linear_allocator.h
index 60d19591855..e276afbbb68 100644
--- a/source/blender/blenlib/BLI_linear_allocator.h
+++ b/source/blender/blenlib/BLI_linear_allocator.h
@@ -27,39 +27,51 @@
 #include "BLI_vector.h"
 #include "BLI_utility_mixins.h"
 #include "BLI_timeit.h"
+#include "BLI_stack_cxx.h"
 #include "BLI_string_ref.h"
 
 namespace BLI {
 
-template<uint N = 0, typename Allocator = GuardedAllocator>
-class LinearAllocator : NonCopyable, NonMovable {
+template<typename Allocator = GuardedAllocator> class LinearAllocator : NonCopyable, NonMovable {
  private:
   Allocator m_allocator;
-  Vector<void *> m_pointers;
+  Vector<void *> m_owned_buffers;
+  Vector<ArrayRef<char>> m_unused_borrowed_buffers;
 
-  void *m_current_buffer;
-  uint m_remaining_capacity;
+  uintptr_t m_current_begin;
+  uintptr_t m_current_end;
   uint m_next_min_alloc_size;
 
-  AlignedBuffer<N, 8> m_inline_buffer;
-
 #ifdef DEBUG
   uint m_debug_allocated_amount = 0;
 #endif
 
  public:
-  LinearAllocator() : m_remaining_capacity(N), m_next_min_alloc_size(std::max<uint>(N * 2, 16))
+  LinearAllocator()
   {
-    m_current_buffer = m_inline_buffer.ptr();
+    m_current_begin = 0;
+    m_current_end = 0;
+    m_next_min_alloc_size = 64;
   }
 
   ~LinearAllocator()
   {
-    for (void *ptr : m_pointers) {
+    for (void *ptr : m_owned_buffers) {
       m_allocator.deallocate(ptr);
     }
   }
 
+  void provide_buffer(void *buffer, uint size)
+  {
+    m_unused_borrowed_buffers.append(ArrayRef<char>((char *)buffer, size));
+  }
+
+  template<uint Size, uint Alignment>
+  void provide_buffer(AlignedBuffer<Size, Alignment> &aligned_buffer)
+  {
+    this->provide_buffer(aligned_buffer.ptr(), Size);
+  }
+
   template<typename T> T *allocate()
   {
     return (T *)this->allocate(sizeof(T), alignof(T));
@@ -80,15 +92,11 @@ class LinearAllocator : NonCopyable, NonMovable {
 #endif
 
     uintptr_t alignment_mask = alignment - 1;
-
-    uintptr_t current_buffer = (uintptr_t)m_current_buffer;
-    uintptr_t potential_allocation_begin = (current_buffer + alignment - 1) & ~alignment_mask;
+    uintptr_t potential_allocation_begin = (m_current_begin + alignment_mask) & ~alignment_mask;
     uintptr_t potential_allocation_end = potential_allocation_begin + size;
-    uintptr_t required_size = potential_allocation_end - current_buffer;
 
-    if (required_size <= m_remaining_capacity) {
-      m_remaining_capacity -= required_size;
-      m_current_buffer = (void *)potential_allocation_end;
+    if (potential_allocation_end <= m_current_end) {
+      m_current_begin = potential_allocation_end;
       return (void *)potential_allocation_begin;
     }
     else {
@@ -140,13 +148,23 @@ class LinearAllocator : NonCopyable, NonMovable {
  private:
   void allocate_new_buffer(uint min_allocation_size)
   {
+    for (uint i : m_unused_borrowed_buffers.index_range()) {
+      ArrayRef<char> buffer = m_unused_borrowed_buffers[i];
+      if (buffer.size() >= min_allocation_size) {
+        m_unused_borrowed_buffers.remove_and_reorder(i);
+        m_current_begin = (uintptr_t)buffer.begin();
+        m_current_end = (uintptr_t)buffer.end();
+        return;
+      }
+    }
+
     uint size_in_bytes = power_of_2_min_u(std::max(min_allocation_size, m_next_min_alloc_size));
     m_next_min_alloc_size = size_in_bytes * 2;
 
     void *buffer = m_allocator.allocate(size_in_bytes, __func__);
-    m_pointers.append(buffer);
-    m_remaining_capacity = size_in_bytes;
-    m_current_buffer = buffer;
+    m_owned_buffers.append(buffer);
+    m_current_begin = (uintptr_t)buffer;
+    m_current_end = m_current_begin + size_in_bytes;
   }
 };
 
diff --git a/source/blender/blenlib/BLI_multi_map.h b/source/blender/blenlib/BLI_multi_map.h
index bb98da6d3d4..b770dfbab6c 100644
--- a/source/blender/blenlib/BLI_multi_map.h
+++ b/source/blender/blenlib/BLI_multi_map.h
@@ -37,7 +37,7 @@ template<typename KeyT, typename ValueT, uint N = 4> class MultiMap {
     uint capacity = 0;
   };
 
-  LinearAllocator<sizeof(ValueT) * N> m_allocator;
+  LinearAllocator<> m_allocator;
   Map<KeyT, Entry> m_map;
 
  public:
diff --git a/source/blender/functions/FN_attributes_ref.h b/source/blender/functions/FN_attributes_ref.h
index 6c9d992798f..4a51ea3fec9 100644
--- a/source/blender/functions/FN_attributes_ref.h
+++ b/source/blender/functions/FN_attributes_ref.h
@@ -27,7 +27,7 @@ class AttributesInfo;
 
 class AttributesInfoBuilder : BLI::NonCopyable, BLI::NonMovable {
  private:
-  LinearAllocator<32> m_allocator;
+  LinearAllocator<> m_allocator;
   VectorSet<std::string> m_names;
   Vector<const CPPType *> m_types;
   Vector<void *> m_defaults;
@@ -100,7 +100,7 @@ class AttributesInfoBuilder : BLI::NonCopyable, BLI::NonMovable {
 
 class AttributesInfo : BLI::NonCopyable, BLI::NonMovable {
  private:
-  LinearAllocator<32> m_allocator;
+  LinearAllocator<> m_allocator;
   StringMap<int> m_index_by_name;
   Vector<std::string> m_name_by_index;
   Vector<const CPPType *> m_type_by_index;
diff --git a/source/blender/functions/intern/multi_functions/network.cc b/source/blender/functions/intern/multi_functions/network.cc
index 39f3e5786dd..a180aada861 100644
--- a/source/blender/functions/intern/multi_functions/network.cc
+++ b/source/blender/functions/intern/multi_functions/network.cc
@@ -104,7 +104,7 @@ struct OwnVectorValue : public Value {
 
 class NetworkEvaluationStorage {
  private:
-  LinearAllocator<256> m_allocator;
+  LinearAllocator<> m_allocator;
   BufferCache &m_buffer_cache;
   IndexMask m_mask;
   Array<Value *> m_value_per_output_id;
diff --git a/tests/gtests/blenlib/BLI_linear_allocator_test.cc b/tests/gtests/blenlib/BLI_linear_allocator_test.cc
index 6d80a0957ce..39280afadcc 100644
--- a/tests/gtests/blenlib/BLI_linear_allocator_test.cc
+++ b/tests/gtests/blenlib/BLI_linear_allocator_test.cc
@@ -28,8 +28,9 @@ TEST(monotonic_allocator, AllocationAlignment)
 
 TEST(monotonic_allocator, PackedAllocation)
 {
-  LinearAllocator<256> allocator;
-  allocator.allocate(32, 32);
+  LinearAllocator<> allocator;
+  BLI::AlignedBuffer<256, 32> buffer;
+  allocator.provide_buffer(buffer);
 
   uintptr_t ptr1 = (uintptr_t)allocator.allocate(10, 4); /*  0 - 10 */
   uintptr_t ptr2 = (uintptr_t)allocator.allocate(10, 4); /* 12 - 22 */



More information about the Bf-blender-cvs mailing list