[Bf-blender-cvs] [5419ae4d831] functions: optimize generic extend operation

Jacques Lucke noreply at git.blender.org
Sat Dec 14 17:45:05 CET 2019


Commit: 5419ae4d831b2c7c01de3d2f2665de5c6534fa6d
Author: Jacques Lucke
Date:   Sat Dec 14 16:19:16 2019 +0100
Branches: functions
https://developer.blender.org/rB5419ae4d831b2c7c01de3d2f2665de5c6534fa6d

optimize generic extend operation

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

M	source/blender/functions/FN_cpp_type.h
M	source/blender/functions/FN_generic_vector_array.h
M	source/blender/functions/FN_generic_virtual_list_ref.h
M	source/blender/functions/intern/cpp_types.cc

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

diff --git a/source/blender/functions/FN_cpp_type.h b/source/blender/functions/FN_cpp_type.h
index 6e53a2d5354..faf86c2eb89 100644
--- a/source/blender/functions/FN_cpp_type.h
+++ b/source/blender/functions/FN_cpp_type.h
@@ -18,6 +18,7 @@ class CPPType {
   using DestructNF = void (*)(void *ptr, uint n);
   using CopyToInitializedF = void (*)(const void *src, void *dst);
   using CopyToUninitializedF = void (*)(const void *src, void *dst);
+  using CopyToUninitializedNF = void (*)(const void *src, void *dst, uint n);
   using RelocateToInitializedF = void (*)(void *src, void *dst);
   using RelocateToUninitializedF = void (*)(void *src, void *dst);
   using RelocateToUninitializedNF = void (*)(void *src, void *dst, uint n);
@@ -32,6 +33,7 @@ class CPPType {
           DestructNF destruct_n,
           CopyToInitializedF copy_to_initialized,
           CopyToUninitializedF copy_to_uninitialized,
+          CopyToUninitializedNF copy_to_uninitialized_n,
           RelocateToInitializedF relocate_to_initialized,
           RelocateToUninitializedF relocate_to_uninitialized,
           RelocateToUninitializedNF relocate_to_uninitialized_n,
@@ -45,6 +47,7 @@ class CPPType {
         m_destruct_n(destruct_n),
         m_copy_to_initialized(copy_to_initialized),
         m_copy_to_uninitialized(copy_to_uninitialized),
+        m_copy_to_uninitialized_n(copy_to_uninitialized_n),
         m_relocate_to_initialized(relocate_to_initialized),
         m_relocate_to_uninitialized(relocate_to_uninitialized),
         m_relocate_to_uninitialized_n(relocate_to_uninitialized_n),
@@ -134,6 +137,14 @@ class CPPType {
     m_copy_to_uninitialized(src, dst);
   }
 
+  void copy_to_uninitialized_n(const void *src, void *dst, uint n) const
+  {
+    BLI_assert(this->pointer_has_valid_alignment(src));
+    BLI_assert(this->pointer_has_valid_alignment(dst));
+
+    m_copy_to_uninitialized_n(src, dst, n);
+  }
+
   void relocate_to_initialized(void *src, void *dst) const
   {
     BLI_assert(this->pointer_has_valid_alignment(src));
@@ -190,6 +201,7 @@ class CPPType {
   DestructNF m_destruct_n;
   CopyToInitializedF m_copy_to_initialized;
   CopyToUninitializedF m_copy_to_uninitialized;
+  CopyToUninitializedNF m_copy_to_uninitialized_n;
   RelocateToInitializedF m_relocate_to_initialized;
   RelocateToUninitializedF m_relocate_to_uninitialized;
   RelocateToUninitializedNF m_relocate_to_uninitialized_n;
diff --git a/source/blender/functions/FN_generic_vector_array.h b/source/blender/functions/FN_generic_vector_array.h
index 298f879c67a..44cd82e8af5 100644
--- a/source/blender/functions/FN_generic_vector_array.h
+++ b/source/blender/functions/FN_generic_vector_array.h
@@ -92,9 +92,35 @@ class GenericVectorArray : BLI::NonCopyable, BLI::NonMovable {
 
   void extend_single__copy(uint index, const GenericVirtualListRef &values)
   {
-    for (uint i = 0; i < values.size(); i++) {
-      this->append_single__copy(index, values[i]);
+    uint extend_length = values.size();
+    uint old_length = m_lengths[index];
+    uint new_length = old_length + extend_length;
+
+    if (new_length >= m_capacities[index]) {
+      this->grow_single(index, new_length);
+    }
+
+    void *start = POINTER_OFFSET(m_starts[index], old_length * m_element_size);
+
+    if (values.is_single_element()) {
+      const void *value = values.as_single_element();
+      for (uint i = 0; i < extend_length; i++) {
+        void *dst = POINTER_OFFSET(start, m_element_size * i);
+        m_type.copy_to_uninitialized(value, dst);
+      }
     }
+    else if (values.is_non_single_full_array()) {
+      GenericArrayRef array = values.as_full_array();
+      m_type.copy_to_uninitialized_n(array.buffer(), start, extend_length);
+    }
+    else {
+      for (uint i = 0; i < extend_length; i++) {
+        void *dst = POINTER_OFFSET(start, m_element_size * i);
+        m_type.copy_to_uninitialized(values[i], dst);
+      }
+    }
+
+    m_lengths[index] = new_length;
   }
 
   GenericMutableArrayRef allocate_single(uint index, uint size)
@@ -187,11 +213,7 @@ class GenericVectorArray : BLI::NonCopyable, BLI::NonMovable {
     void *new_buffer = m_elements_allocator.allocate(m_element_size * min_capacity,
                                                      m_type.alignment());
 
-    for (uint i = 0; i < m_lengths[index]; i++) {
-      void *src = POINTER_OFFSET(m_starts[index], m_element_size * i);
-      void *dst = POINTER_OFFSET(new_buffer, m_element_size * i);
-      m_type.relocate_to_uninitialized(src, dst);
-    }
+    m_type.relocate_to_uninitialized_n(m_starts[index], new_buffer, m_lengths[index]);
 
     m_starts[index] = new_buffer;
     m_capacities[index] = min_capacity;
diff --git a/source/blender/functions/FN_generic_virtual_list_ref.h b/source/blender/functions/FN_generic_virtual_list_ref.h
index 0646a18a210..56d41ac2162 100644
--- a/source/blender/functions/FN_generic_virtual_list_ref.h
+++ b/source/blender/functions/FN_generic_virtual_list_ref.h
@@ -139,6 +139,23 @@ class GenericVirtualListRef {
     return false;
   }
 
+  const void *as_single_element() const
+  {
+    BLI_assert(this->is_single_element());
+    return (*this)[0];
+  }
+
+  bool is_non_single_full_array() const
+  {
+    return m_category == Category::FullArray && m_virtual_size > 1;
+  }
+
+  GenericArrayRef as_full_array() const
+  {
+    BLI_assert(m_category == Category::FullArray);
+    return GenericArrayRef(*m_type, m_data.full_array.data, m_virtual_size);
+  }
+
   uint size() const
   {
     return m_virtual_size;
diff --git a/source/blender/functions/intern/cpp_types.cc b/source/blender/functions/intern/cpp_types.cc
index 2e639030bfd..fb9f3d47266 100644
--- a/source/blender/functions/intern/cpp_types.cc
+++ b/source/blender/functions/intern/cpp_types.cc
@@ -43,6 +43,10 @@ template<typename T> void CopyToUninitialized_CB(const void *src, void *dst)
 {
   BLI::uninitialized_copy_n((T *)src, 1, (T *)dst);
 }
+template<typename T> void CopyToUninitializedN_CB(const void *src, void *dst, uint n)
+{
+  BLI::uninitialized_copy_n((T *)src, n, (T *)dst);
+}
 template<typename T> void RelocateToInitialized_CB(void *src, void *dst)
 {
   BLI::relocate((T *)src, (T *)dst);
@@ -68,6 +72,7 @@ template<typename T> static std::unique_ptr<const CPPType> create_cpp_type(Strin
                                     DestructN_CB<T>,
                                     CopyToInitialized_CB<T>,
                                     CopyToUninitialized_CB<T>,
+                                    CopyToUninitializedN_CB<T>,
                                     RelocateToInitialized_CB<T>,
                                     RelocateToUninitialized_CB<T>,
                                     RelocateToUninitializedN_CB<T>,



More information about the Bf-blender-cvs mailing list