[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