[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