Page MenuHome
Paste P3088

D14938 alternative, threading via BM_iter_parallel with timing comparison
ActivePublic

Authored by Campbell Barton (campbellbarton) on Jul 19 2022, 5:58 AM.
diff --git a/source/blender/blenkernel/intern/editmesh_cache.cc b/source/blender/blenkernel/intern/editmesh_cache.cc
index 438d287fb28..eab873535c7 100644
--- a/source/blender/blenkernel/intern/editmesh_cache.cc
+++ b/source/blender/blenkernel/intern/editmesh_cache.cc
@@ -11,6 +11,7 @@
#include "BLI_bounds.hh"
#include "BLI_math_vector.h"
#include "BLI_span.hh"
+#include "BLI_task.h"
#include "DNA_mesh_types.h"
@@ -111,6 +112,33 @@ void BKE_editmesh_cache_ensure_poly_centers(BMEditMesh *em, EditMeshData *emd)
/** \name Calculate Min/Max
* \{ */
+using BMVertsCalcBoundsData = struct BMVertsCalcBoundsData {
+ float min[3];
+ float max[3];
+};
+
+static void bm_vert_calc_bounds_fn(void *userdata,
+ MempoolIterData *mp_v,
+ const TaskParallelTLS *__restrict UNUSED(tls))
+{
+ BMVertsCalcBoundsData *data = (BMVertsCalcBoundsData *)userdata;
+ BMVert *v = (BMVert *)mp_v;
+ minmax_v3v3_v3(data->min, data->max, v->co);
+}
+static void bm_vert_calc_bounds_reduce_fn(const void *__restrict UNUSED(userdata),
+ void *__restrict chunk_join,
+ void *__restrict chunk)
+{
+ BMVertsCalcBoundsData *dst = (BMVertsCalcBoundsData *)chunk_join;
+ const BMVertsCalcBoundsData *src = (BMVertsCalcBoundsData *)chunk;
+ for (int i = 0; i < 3; i++) {
+ dst->min[i] = min_ff(dst->min[i], src->min[i]);
+ dst->max[i] = max_ff(dst->max[i], src->max[i]);
+ }
+}
+#include "PIL_time.h"
+#include "PIL_time_utildefines.h"
+
bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em,
struct EditMeshData *emd,
float min[3],
@@ -128,10 +156,80 @@ bool BKE_editmesh_cache_calc_minmax(struct BMEditMesh *em,
copy_v3_v3(max, math::max(bounds->max, float3(max)));
}
else {
- BMVert *eve;
- BMIter iter;
- BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
- minmax_v3v3_v3(min, max, eve->co);
+ if (bm->totvert < 1) {
+ INIT_MINMAX(min, max);
+ BMVert *eve;
+ BMIter iter;
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ minmax_v3v3_v3(min, max, eve->co);
+ }
+ }
+ else {
+ TIMEIT_START(multi);
+
+ BMVertsCalcBoundsData chunk_data;
+ INIT_MINMAX(chunk_data.min, chunk_data.max);
+
+ TaskParallelSettings settings;
+ BLI_parallel_range_settings_defaults(&settings);
+ settings.use_threading = true;
+ settings.userdata_chunk = &chunk_data;
+ settings.userdata_chunk_size = sizeof(chunk_data);
+ settings.func_reduce = bm_vert_calc_bounds_reduce_fn;
+
+ BM_iter_parallel(bm, BM_VERTS_OF_MESH, bm_vert_calc_bounds_fn, &chunk_data, &settings);
+
+ copy_v3_v3(min, chunk_data.min);
+ copy_v3_v3(max, chunk_data.max);
+
+ TIMEIT_END(multi);
+
+ print_v3_id(min);
+ print_v3_id(max);
+
+ TIMEIT_START(single);
+
+ INIT_MINMAX(min, max);
+ BMVert *eve;
+ BMIter iter;
+ BM_ITER_MESH (eve, &iter, bm, BM_VERTS_OF_MESH) {
+ minmax_v3v3_v3(min, max, eve->co);
+ }
+
+ TIMEIT_END(single);
+
+ print_v3_id(min);
+ print_v3_id(max);
+
+ BM_mesh_elem_table_ensure(bm, BM_VERT);
+
+ TIMEIT_START(multi_x);
+
+ struct Result {
+ float3 min;
+ float3 max;
+ };
+
+ const Result bounds = threading::parallel_reduce(
+ IndexRange(bm->totvert),
+ 1024,
+ Result{float3(FLT_MAX), float3(-FLT_MAX)},
+ [&](IndexRange range, const Result &init) {
+ Result result = init;
+ for (const int i : range) {
+ const BMVert &vert = *BM_vert_at_index(bm, i);
+ math::min_max(float3(vert.co), result.min, result.max);
+ }
+ return result;
+ },
+ [](const Result &a, const Result &b) {
+ return Result{math::min(a.min, b.min), math::max(a.max, b.max)};
+ });
+
+ copy_v3_v3(min, math::min(bounds.min, float3(min)));
+ copy_v3_v3(max, math::max(bounds.max, float3(max)));
+
+ TIMEIT_END(multi_x);
}
}
return true;

Event Timeline

Campbell Barton (campbellbarton) changed the title of this paste from D14938 timing tests to D14938 alternative, threading via BM_iter_parallel.
Campbell Barton (campbellbarton) changed the title of this paste from D14938 alternative, threading via BM_iter_parallel to D14938 alternative, threading via BM_iter_parallel with timing comparison.