[Bf-blender-cvs] [cbe9a87d282] master: Geometry Nodes: use simpler types when devirtualizing virtual array

Jacques Lucke noreply at git.blender.org
Wed Nov 24 17:46:10 CET 2021


Commit: cbe9a87d282f8060670b2162a87995a255dda556
Author: Jacques Lucke
Date:   Wed Nov 24 17:46:00 2021 +0100
Branches: master
https://developer.blender.org/rBcbe9a87d282f8060670b2162a87995a255dda556

Geometry Nodes: use simpler types when devirtualizing virtual array

The compiler is more likely to optimize away the function call
overhead when the used type is simpler and not virtual.

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

M	source/blender/blenlib/BLI_virtual_array.hh

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

diff --git a/source/blender/blenlib/BLI_virtual_array.hh b/source/blender/blenlib/BLI_virtual_array.hh
index d9f83d3e1cb..b8b05e88572 100644
--- a/source/blender/blenlib/BLI_virtual_array.hh
+++ b/source/blender/blenlib/BLI_virtual_array.hh
@@ -1107,6 +1107,30 @@ template<typename T> class VMutableArray_Span final : public MutableSpan<T> {
   }
 };
 
+template<typename T> class SingleAsSpan {
+ private:
+  T value_;
+  int64_t size_;
+
+ public:
+  SingleAsSpan(T value, int64_t size) : value_(std::move(value)), size_(size)
+  {
+    BLI_assert(size_ >= 0);
+  }
+
+  SingleAsSpan(const VArray<T> &varray) : SingleAsSpan(varray.get_internal_single(), varray.size())
+  {
+  }
+
+  const T &operator[](const int64_t index) const
+  {
+    BLI_assert(index >= 0);
+    BLI_assert(index < size_);
+    UNUSED_VARS_NDEBUG(index);
+    return value_;
+  }
+};
+
 /**
  * Generate multiple versions of the given function optimized for different virtual arrays.
  * One has to be careful with nesting multiple devirtualizations, because that results in an
@@ -1121,14 +1145,11 @@ inline void devirtualize_varray(const VArray<T> &varray, const Func &func, bool
   /* Support disabling the devirtualization to simplify benchmarking. */
   if (enable) {
     if (varray.is_single()) {
-      /* `VArrayImpl_For_Single` can be used for devirtualization, because it is declared `final`.
-       */
-      func(VArray<T>::ForSingle(varray.get_internal_single(), varray.size()));
+      func(SingleAsSpan<T>(varray));
       return;
     }
     if (varray.is_span()) {
-      /* `VArrayImpl_For_Span` can be used for devirtualization, because it is declared `final`. */
-      func(VArray<T>::ForSpan(varray.get_internal_span()));
+      func(varray.get_internal_span());
       return;
     }
   }
@@ -1153,23 +1174,19 @@ inline void devirtualize_varray2(const VArray<T1> &varray1,
     const bool is_single1 = varray1.is_single();
     const bool is_single2 = varray2.is_single();
     if (is_span1 && is_span2) {
-      func(VArray<T1>::ForSpan(varray1.get_internal_span()),
-           VArray<T2>::ForSpan(varray2.get_internal_span()));
+      func(varray1.get_internal_span(), varray2.get_internal_span());
       return;
     }
     if (is_span1 && is_single2) {
-      func(VArray<T1>::ForSpan(varray1.get_internal_span()),
-           VArray<T2>::ForSingle(varray2.get_internal_single(), varray2.size()));
+      func(varray1.get_internal_span(), SingleAsSpan(varray2));
       return;
     }
     if (is_single1 && is_span2) {
-      func(VArray<T1>::ForSingle(varray1.get_internal_single(), varray1.size()),
-           VArray<T2>::ForSpan(varray2.get_internal_span()));
+      func(SingleAsSpan(varray1), varray2.get_internal_span());
       return;
     }
     if (is_single1 && is_single2) {
-      func(VArray<T1>::ForSingle(varray1.get_internal_single(), varray1.size()),
-           VArray<T2>::ForSingle(varray2.get_internal_single(), varray2.size()));
+      func(SingleAsSpan(varray1), SingleAsSpan(varray2));
       return;
     }
   }



More information about the Bf-blender-cvs mailing list