[Bf-blender-cvs] [2f339eb745d] master: BKE: improve calculating edges

Jacques Lucke noreply at git.blender.org
Fri Oct 9 12:40:04 CEST 2020


Commit: 2f339eb745df31c3035c737a1013dc8bb450beb6
Author: Jacques Lucke
Date:   Fri Oct 9 12:37:42 2020 +0200
Branches: master
https://developer.blender.org/rB2f339eb745df31c3035c737a1013dc8bb450beb6

BKE: improve calculating edges

This is a follow up commit for rB309c919ee9.
Clearing hash tables is now parallelized as well. Surprisingly, most of
the time is actually spent in `free` (a couple of milliseconds per call
in my test).

Benchmark of individual functions:
reserve_hash_maps: 17%
add_polygon_edges_to_hash_maps: 49%
serialize_and_initialize_deduplicated_edges: 12%
update_edge_indices_in_poly_loops: 14%
clear_hash_tables: 5%

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

M	source/blender/blenkernel/intern/mesh_validate.cc

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

diff --git a/source/blender/blenkernel/intern/mesh_validate.cc b/source/blender/blenkernel/intern/mesh_validate.cc
index 64fddc81124..16733729be0 100644
--- a/source/blender/blenkernel/intern/mesh_validate.cc
+++ b/source/blender/blenkernel/intern/mesh_validate.cc
@@ -82,6 +82,15 @@ typedef union OrigEdgeOrIndex {
 } OrigEdgeOrIndex;
 using EdgeMap = Map<OrderedEdge, OrigEdgeOrIndex>;
 
+static void reserve_hash_maps(const Mesh *mesh,
+                              const bool keep_existing_edges,
+                              MutableSpan<EdgeMap> edge_maps)
+{
+  const int totedge_guess = std::max(keep_existing_edges ? mesh->totedge : 0, mesh->totpoly * 2);
+  parallel_for_each(
+      edge_maps, [&](EdgeMap &edge_map) { edge_map.reserve(totedge_guess / edge_maps.size()); });
+}
+
 static void add_existing_edges_to_hash_maps(Mesh *mesh,
                                             MutableSpan<EdgeMap> edge_maps,
                                             uint32_t parallel_mask)
@@ -204,6 +213,11 @@ static int get_parallel_maps_count(const Mesh *mesh)
   return power_of_2_min_i(std::min(8, system_thread_count));
 }
 
+static void clear_hash_tables(MutableSpan<EdgeMap> edge_maps)
+{
+  parallel_for_each(edge_maps, [](EdgeMap &edge_map) { edge_map.clear(); });
+}
+
 }  // namespace blender::bke::calc_edges
 
 /**
@@ -221,11 +235,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
   BLI_assert(is_power_of_2_i(parallel_maps));
   const uint32_t parallel_mask = static_cast<uint32_t>(parallel_maps) - 1;
   Array<EdgeMap> edge_maps(parallel_maps);
-
-  /* Reserve memory in hash tables. */
-  const int totedge_guess = std::max(keep_existing_edges ? mesh->totedge : 0, mesh->totpoly * 2);
-  parallel_for_each(edge_maps,
-                    [&](EdgeMap &edge_map) { edge_map.reserve(totedge_guess / parallel_maps); });
+  reserve_hash_maps(mesh, keep_existing_edges, edge_maps);
 
   /* Add all edges. */
   if (keep_existing_edges) {
@@ -252,4 +262,7 @@ void BKE_mesh_calc_edges(Mesh *mesh, bool keep_existing_edges, const bool select
   CustomData_add_layer(&mesh->edata, CD_MEDGE, CD_ASSIGN, new_edges.data(), new_totedge);
   mesh->totedge = new_totedge;
   mesh->medge = new_edges.data();
+
+  /* Explicitely clear edge maps, because that way it can be parallelized. */
+  clear_hash_tables(edge_maps);
 }



More information about the Bf-blender-cvs mailing list