diff options
author | Jacques Lucke <jacques@blender.org> | 2020-10-09 13:37:42 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2020-10-09 13:37:42 +0300 |
commit | 2f339eb745df31c3035c737a1013dc8bb450beb6 (patch) | |
tree | da3cfdaaf253696e1e2ef5161687b6eb9db282f6 | |
parent | 309c919ee97e272c08f88ebd8341fe962e71e64d (diff) |
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%
-rw-r--r-- | source/blender/blenkernel/intern/mesh_validate.cc | 23 |
1 files changed, 18 insertions, 5 deletions
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); } |