[Bf-blender-cvs] [b513c89e845] master: Functions: avoid using Map for small values

Jacques Lucke noreply at git.blender.org
Sat Jun 25 18:53:41 CEST 2022


Commit: b513c89e8450289746a7b3397bf3d610a0989d79
Author: Jacques Lucke
Date:   Sat Jun 25 18:52:55 2022 +0200
Branches: master
https://developer.blender.org/rBb513c89e8450289746a7b3397bf3d610a0989d79

Functions: avoid using Map for small values

This leads to a 5-10% performance improvement in my benchmark
that runs a procedure many times on a single element.

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

M	source/blender/blenlib/BLI_cpp_type.hh
M	source/blender/functions/intern/multi_function_procedure_executor.cc

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

diff --git a/source/blender/blenlib/BLI_cpp_type.hh b/source/blender/blenlib/BLI_cpp_type.hh
index ed680214602..cc48b456da7 100644
--- a/source/blender/blenlib/BLI_cpp_type.hh
+++ b/source/blender/blenlib/BLI_cpp_type.hh
@@ -626,6 +626,11 @@ class CPPType : NonCopyable, NonMovable {
     fill_construct_indices_(value, dst, mask);
   }
 
+  bool can_exist_in_buffer(const int64_t buffer_size, const int64_t buffer_alignment) const
+  {
+    return size_ <= buffer_size && alignment_ <= buffer_alignment;
+  }
+
   void print(const void *value, std::stringstream &ss) const
   {
     BLI_assert(this->pointer_can_point_to_instance(value));
diff --git a/source/blender/functions/intern/multi_function_procedure_executor.cc b/source/blender/functions/intern/multi_function_procedure_executor.cc
index a45240dad55..d92ce80bceb 100644
--- a/source/blender/functions/intern/multi_function_procedure_executor.cc
+++ b/source/blender/functions/intern/multi_function_procedure_executor.cc
@@ -147,11 +147,11 @@ class ValueAllocator : NonCopyable, NonMovable {
   Map<int, Stack<void *>> span_buffers_free_list_;
 
   /** Cache buffers for single values of different types. */
+  static constexpr inline int small_value_max_size = 16;
+  static constexpr inline int small_value_max_alignment = 8;
+  Stack<void *> small_single_value_free_list_;
   Map<const CPPType *, Stack<void *>> single_value_free_lists_;
 
-  /** The cached memory buffers can hold #VariableState values. */
-  Stack<void *> variable_state_free_list_;
-
  public:
   ValueAllocator(LinearAllocator<> &linear_allocator) : linear_allocator_(linear_allocator)
   {
@@ -210,10 +210,15 @@ class ValueAllocator : NonCopyable, NonMovable {
 
   VariableValue_OneSingle *obtain_OneSingle(const CPPType &type)
   {
-    Stack<void *> &stack = single_value_free_lists_.lookup_or_add_default(&type);
+    const bool is_small = type.can_exist_in_buffer(small_value_max_size,
+                                                   small_value_max_alignment);
+    Stack<void *> &stack = is_small ? small_single_value_free_list_ :
+                                      single_value_free_lists_.lookup_or_add_default(&type);
     void *buffer;
     if (stack.is_empty()) {
-      buffer = linear_allocator_.allocate(type.size(), type.alignment());
+      buffer = linear_allocator_.allocate(
+          std::max<int>(small_value_max_size, type.size()),
+          std::max<int>(small_value_max_alignment, type.alignment()));
     }
     else {
       buffer = stack.pop();
@@ -259,7 +264,14 @@ class ValueAllocator : NonCopyable, NonMovable {
         if (value_typed->is_initialized) {
           type.destruct(value_typed->data);
         }
-        single_value_free_lists_.lookup_or_add_default(&type).push(value_typed->data);
+        const bool is_small = type.can_exist_in_buffer(small_value_max_size,
+                                                       small_value_max_alignment);
+        if (is_small) {
+          small_single_value_free_list_.push(value_typed->data);
+        }
+        else {
+          single_value_free_lists_.lookup_or_add_default(&type).push(value_typed->data);
+        }
         break;
       }
       case ValueType::OneVector: {



More information about the Bf-blender-cvs mailing list