[Bf-blender-cvs] [4755ab5b507] functions: optimize variadic math functions
Jacques Lucke
noreply at git.blender.org
Tue Dec 10 14:37:36 CET 2019
Commit: 4755ab5b50724049070920f2936b58f5bf1da8c9
Author: Jacques Lucke
Date: Tue Dec 10 14:05:31 2019 +0100
Branches: functions
https://developer.blender.org/rB4755ab5b50724049070920f2936b58f5bf1da8c9
optimize variadic math functions
===================================================================
M source/blender/blenlib/BLI_virtual_list_ref.h
M source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
===================================================================
diff --git a/source/blender/blenlib/BLI_virtual_list_ref.h b/source/blender/blenlib/BLI_virtual_list_ref.h
index 324be32ecf8..80d46bed8d0 100644
--- a/source/blender/blenlib/BLI_virtual_list_ref.h
+++ b/source/blender/blenlib/BLI_virtual_list_ref.h
@@ -143,9 +143,9 @@ template<typename T> class VirtualListRef {
return m_virtual_size;
}
- bool is_full_array() const
+ bool is_non_single_full_array() const
{
- return m_category == Category::FullArray;
+ return m_category == Category::FullArray && m_virtual_size > 1;
}
ArrayRef<T> as_full_array() const
diff --git a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
index b235830f184..ad6d0e4c9a8 100644
--- a/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
+++ b/source/blender/functions/intern/inlined_tree_multi_function_network/mappings_nodes.cc
@@ -144,25 +144,28 @@ static void build_math_fn_in2_out1(VNodeMFNetworkBuilder &builder, FuncT func)
VirtualListRef<InT1> inputs1,
VirtualListRef<InT2> inputs2,
MutableArrayRef<OutT> outputs) -> void {
- if (inputs1.is_full_array() && inputs2.is_full_array()) {
+ if (inputs1.is_non_single_full_array() && inputs2.is_non_single_full_array()) {
ArrayRef<InT1> in1_array = inputs1.as_full_array();
ArrayRef<InT2> in2_array = inputs2.as_full_array();
-
mask.foreach_index(
[=](uint i) { new (&outputs[i]) OutT(func(in1_array[i], in2_array[i])); });
}
- else if (inputs1.is_full_array() && inputs2.is_single_element()) {
+ else if (inputs1.is_non_single_full_array() && inputs2.is_single_element()) {
ArrayRef<InT1> in1_array = inputs1.as_full_array();
InT2 in2_single = inputs2[0];
-
mask.foreach_index([=](uint i) { new (&outputs[i]) OutT(func(in1_array[i], in2_single)); });
}
- else if (inputs1.is_single_element() && inputs2.is_full_array()) {
+ else if (inputs1.is_single_element() && inputs2.is_non_single_full_array()) {
InT1 in1_single = inputs1[0];
ArrayRef<InT2> in2_array = inputs2.as_full_array();
-
mask.foreach_index([=](uint i) { new (&outputs[i]) OutT(func(in1_single, in2_array[i])); });
}
+ else if (inputs1.is_single_element() && inputs2.is_single_element()) {
+ InT1 in1_single = inputs1[0];
+ InT2 in2_single = inputs2[0];
+ OutT out_single = func(in1_single, in2_single);
+ outputs.fill_indices(mask.indices(), out_single);
+ }
else {
mask.foreach_index([=](uint i) { new (&outputs[i]) OutT(func(inputs1[i], inputs2[i])); });
}
@@ -172,17 +175,36 @@ static void build_math_fn_in2_out1(VNodeMFNetworkBuilder &builder, FuncT func)
{"use_list__a", "use_list__b"}, builder.xnode().name(), fn);
}
-template<typename T>
-static void build_variadic_math_fn(VNodeMFNetworkBuilder &builder,
- T (*func)(T, T),
- T default_value)
+template<typename T, typename FuncT>
+static void build_variadic_math_fn(VNodeMFNetworkBuilder &builder, FuncT func, T default_value)
{
- auto fn = [func](MFMask mask,
- VirtualListRef<T> inputs1,
- VirtualListRef<T> inputs2,
- MutableArrayRef<T> outputs) {
- for (uint i : mask.indices()) {
- outputs[i] = func(inputs1[i], inputs2[i]);
+ auto fn = [=](MFMask mask,
+ VirtualListRef<T> inputs1,
+ VirtualListRef<T> inputs2,
+ MutableArrayRef<T> outputs) {
+ if (inputs1.is_non_single_full_array() && inputs2.is_non_single_full_array()) {
+ ArrayRef<T> in1_array = inputs1.as_full_array();
+ ArrayRef<T> in2_array = inputs2.as_full_array();
+ mask.foreach_index([=](uint i) { outputs[i] = func(in1_array[i], in2_array[i]); });
+ }
+ else if (inputs1.is_non_single_full_array() && inputs2.is_single_element()) {
+ ArrayRef<T> in1_array = inputs1.as_full_array();
+ T in2_single = inputs2[0];
+ mask.foreach_index([=](uint i) { outputs[i] = func(in1_array[i], in2_single); });
+ }
+ else if (inputs1.is_single_element() && inputs2.is_non_single_full_array()) {
+ T in1_single = inputs1[0];
+ ArrayRef<T> in2_array = inputs2.as_full_array();
+ mask.foreach_index([=](uint i) { outputs[i] = func(in1_single, in2_array[i]); });
+ }
+ else if (inputs1.is_single_element() && inputs2.is_single_element()) {
+ T in1_single = inputs1[0];
+ T in2_single = inputs2[0];
+ T out_single = func(in1_single, in2_single);
+ outputs.fill_indices(mask.indices(), out_single);
+ }
+ else {
+ mask.foreach_index([=](uint i) { outputs[i] = func(inputs1[i], inputs2[i]); });
}
};
@@ -205,25 +227,25 @@ static void build_variadic_math_fn(VNodeMFNetworkBuilder &builder,
static void INSERT_add_floats(VNodeMFNetworkBuilder &builder)
{
build_variadic_math_fn(
- builder, +[](float a, float b) -> float { return a + b; }, 0.0f);
+ builder, [](float a, float b) -> float { return a + b; }, 0.0f);
}
static void INSERT_multiply_floats(VNodeMFNetworkBuilder &builder)
{
build_variadic_math_fn(
- builder, +[](float a, float b) -> float { return a * b; }, 1.0f);
+ builder, [](float a, float b) -> float { return a * b; }, 1.0f);
}
static void INSERT_minimum_floats(VNodeMFNetworkBuilder &builder)
{
build_variadic_math_fn(
- builder, +[](float a, float b) -> float { return std::min(a, b); }, 0.0f);
+ builder, [](float a, float b) -> float { return std::min(a, b); }, 0.0f);
}
static void INSERT_maximum_floats(VNodeMFNetworkBuilder &builder)
{
build_variadic_math_fn(
- builder, +[](float a, float b) -> float { return std::max(a, b); }, 0.0f);
+ builder, [](float a, float b) -> float { return std::max(a, b); }, 0.0f);
}
static void INSERT_subtract_floats(VNodeMFNetworkBuilder &builder)
@@ -271,12 +293,14 @@ static void INSERT_cosine_float(VNodeMFNetworkBuilder &builder)
static void INSERT_add_vectors(VNodeMFNetworkBuilder &builder)
{
- build_variadic_math_fn(builder, +[](float3 a, float3 b) -> float3 { return a + b; }, {0, 0, 0});
+ build_variadic_math_fn(
+ builder, [](float3 a, float3 b) -> float3 { return a + b; }, float3(0, 0, 0));
}
static void INSERT_multiply_vectors(VNodeMFNetworkBuilder &builder)
{
- build_variadic_math_fn(builder, +[](float3 a, float3 b) -> float3 { return a * b; }, {1, 1, 1});
+ build_variadic_math_fn(
+ builder, [](float3 a, float3 b) -> float3 { return a * b; }, float3(1, 1, 1));
}
static void INSERT_subtract_vectors(VNodeMFNetworkBuilder &builder)
@@ -319,13 +343,13 @@ static void INSERT_vector_distance(VNodeMFNetworkBuilder &builder)
static void INSERT_boolean_and(VNodeMFNetworkBuilder &builder)
{
build_variadic_math_fn(
- builder, +[](bool a, bool b) { return a && b; }, true);
+ builder, [](bool a, bool b) { return a && b; }, true);
}
static void INSERT_boolean_or(VNodeMFNetworkBuilder &builder)
{
build_variadic_math_fn(
- builder, +[](bool a, bool b) { return a || b; }, false);
+ builder, [](bool a, bool b) { return a || b; }, false);
}
static void INSERT_boolean_not(VNodeMFNetworkBuilder &builder)
More information about the Bf-blender-cvs
mailing list