From 3c6c15d67655cc942bdbbb2cbdc94c32d10b184d Mon Sep 17 00:00:00 2001 From: Jacques Lucke Date: Tue, 29 Mar 2022 10:11:49 +0200 Subject: Functions: move loops into function builders This simplifies debugging, and can help improve performance by making it easier for the compiler. More optimization might still be possible by using `__restrict` in a few places. --- .../blender/functions/FN_multi_function_builder.hh | 46 ++++++++++++++++------ 1 file changed, 33 insertions(+), 13 deletions(-) diff --git a/source/blender/functions/FN_multi_function_builder.hh b/source/blender/functions/FN_multi_function_builder.hh index 7ba368d9a9d..2eaada5dea0 100644 --- a/source/blender/functions/FN_multi_function_builder.hh +++ b/source/blender/functions/FN_multi_function_builder.hh @@ -49,8 +49,11 @@ template class CustomMF_SI_SO : public MultiFunctio return [=](IndexMask mask, const VArray &in1, MutableSpan out1) { /* Devirtualization results in a 2-3x speedup for some simple functions. */ devirtualize_varray(in1, [&](const auto &in1) { - mask.foreach_index( - [&](int i) { new (static_cast(&out1[i])) Out1(element_fn(in1[i])); }); + mask.to_best_mask_type([&](const auto &mask) { + for (const int64_t i : mask) { + new (static_cast(&out1[i])) Out1(element_fn(in1[i])); + } + }); }); }; } @@ -102,8 +105,11 @@ class CustomMF_SI_SI_SO : public MultiFunction { MutableSpan out1) { /* Devirtualization results in a 2-3x speedup for some simple functions. */ devirtualize_varray2(in1, in2, [&](const auto &in1, const auto &in2) { - mask.foreach_index( - [&](int i) { new (static_cast(&out1[i])) Out1(element_fn(in1[i], in2[i])); }); + mask.to_best_mask_type([&](const auto &mask) { + for (const int64_t i : mask) { + new (static_cast(&out1[i])) Out1(element_fn(in1[i], in2[i])); + } + }); }); }; } @@ -160,9 +166,11 @@ class CustomMF_SI_SI_SI_SO : public MultiFunction { const VArray &in2, const VArray &in3, MutableSpan out1) { - mask.foreach_index([&](int i) { + /* Virtual arrays are not devirtualized yet, to avoid generating lots of code without further + * consideration. */ + for (const int64_t i : mask) { new (static_cast(&out1[i])) Out1(element_fn(in1[i], in2[i], in3[i])); - }); + } }; } @@ -223,9 +231,11 @@ class CustomMF_SI_SI_SI_SI_SO : public MultiFunction { const VArray &in3, const VArray &in4, MutableSpan out1) { - mask.foreach_index([&](int i) { + /* Virtual arrays are not devirtualized yet, to avoid generating lots of code without further + * consideration. */ + for (const int64_t i : mask) { new (static_cast(&out1[i])) Out1(element_fn(in1[i], in2[i], in3[i], in4[i])); - }); + } }; } @@ -268,7 +278,11 @@ template class CustomMF_SM : public MultiFunction { template static FunctionT create_function(ElementFuncT element_fn) { return [=](IndexMask mask, MutableSpan mut1) { - mask.foreach_index([&](int i) { element_fn(mut1[i]); }); + mask.to_best_mask_type([&](const auto &mask) { + for (const int64_t i : mask) { + element_fn(mut1[i]); + } + }); }; } @@ -304,9 +318,11 @@ template class CustomMF_Convert : public MultiFuncti const VArray &inputs = params.readonly_single_input(0); MutableSpan outputs = params.uninitialized_single_output(1); - for (int64_t i : mask) { - new (static_cast(&outputs[i])) To(inputs[i]); - } + mask.to_best_mask_type([&](const auto &mask) { + for (int64_t i : mask) { + new (static_cast(&outputs[i])) To(inputs[i]); + } + }); } }; @@ -366,7 +382,11 @@ template class CustomMF_Constant : public MultiFunction { void call(IndexMask mask, MFParams params, MFContext UNUSED(context)) const override { MutableSpan output = params.uninitialized_single_output(0); - mask.foreach_index([&](int i) { new (&output[i]) T(value_); }); + mask.to_best_mask_type([&](const auto &mask) { + for (const int64_t i : mask) { + new (&output[i]) T(value_); + } + }); } uint64_t hash() const override -- cgit v1.2.3