diff options
author | Iliay Katueshenock <Moder> | 2022-07-26 12:06:49 +0300 |
---|---|---|
committer | Jacques Lucke <jacques@blender.org> | 2022-07-26 12:10:16 +0300 |
commit | c94ca54cdafdba15d5a7be55e81d6f7a0da7ed7e (patch) | |
tree | fe6644d41f65b4e1d5861c33b465b6371b49306c | |
parent | 203e7ba3320e7ed978ec094efa0c1b22137fb12a (diff) |
BLI: add use_threading parameter to parallel_invoke
`parallel_invoke` allows executing functions on separate threads.
However, creating tasks in tbb has a measurable amount of overhead.
Therefore, it can be benefitial to disable parallelization when
the amount of work done per function is small.
See D15539 for some benchmark results.
Differential Revision: https://developer.blender.org/D15539
7 files changed, 25 insertions, 0 deletions
diff --git a/source/blender/blenkernel/intern/curves_geometry.cc b/source/blender/blenkernel/intern/curves_geometry.cc index 3050e01e528..6486be4afe0 100644 --- a/source/blender/blenkernel/intern/curves_geometry.cc +++ b/source/blender/blenkernel/intern/curves_geometry.cc @@ -1165,6 +1165,7 @@ static CurvesGeometry copy_with_removed_points(const CurvesGeometry &curves, CurvesGeometry new_curves{new_point_count, new_curve_count}; threading::parallel_invoke( + 256 < new_point_count * new_curve_count, /* Initialize curve offsets. */ [&]() { new_curves.offsets_for_write().copy_from(new_curve_offsets); }, [&]() { @@ -1237,6 +1238,7 @@ static CurvesGeometry copy_with_removed_curves(const CurvesGeometry &curves, CurvesGeometry new_curves{new_tot_points, new_tot_curves}; threading::parallel_invoke( + 256 < new_tot_points * new_tot_curves, /* Initialize curve offsets. */ [&]() { MutableSpan<int> new_offsets = new_curves.offsets_for_write(); diff --git a/source/blender/blenlib/BLI_task.hh b/source/blender/blenlib/BLI_task.hh index 904dea66f7a..33a781d3749 100644 --- a/source/blender/blenlib/BLI_task.hh +++ b/source/blender/blenlib/BLI_task.hh @@ -105,6 +105,22 @@ template<typename... Functions> void parallel_invoke(Functions &&...functions) #endif } +/** + * Same #parallel_invoke, but allows disabling threading dynamically. This is useful because when + * the individual functions do very little work, there is a lot of overhead from starting parallel + * tasks. + */ +template<typename... Functions> +void parallel_invoke(const bool use_threading, Functions &&...functions) +{ + if (use_threading) { + parallel_invoke(std::forward<Functions>(functions)...); + } + else { + (functions(), ...); + } +} + /** See #BLI_task_isolate for a description of what isolating a task means. */ template<typename Function> void isolate_task(const Function &function) { diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc index 907c2c29c42..e1ac941eb2b 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_density.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_density.cc @@ -188,6 +188,7 @@ struct DensityAddOperationExecutor { * curves. */ Array<bool> new_curve_skipped(new_positions_cu.size(), false); threading::parallel_invoke( + 512 < already_added_curves + new_positions_cu.size(), /* Build kdtree from root points created by the current stroke. */ [&]() { for (const int i : IndexRange(already_added_curves)) { @@ -309,6 +310,7 @@ struct DensityAddOperationExecutor { }; threading::parallel_invoke( + 1024 < original_positions.size() + deformed_positions.size(), [&]() { self_->original_curve_roots_kdtree_ = roots_kdtree_from_positions(original_positions); }, diff --git a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc index 02ebd622469..4ae4149a2a0 100644 --- a/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc +++ b/source/blender/editors/sculpt_paint/curves_sculpt_ops.cc @@ -734,6 +734,8 @@ static void select_grow_invoke_per_curve(Curves &curves_id, } threading::parallel_invoke( + 1024 < curve_op_data.selected_point_indices.size() + + curve_op_data.unselected_point_indices.size(), [&]() { /* Build KD-tree for the selected points. */ KDTree_3d *kdtree = BLI_kdtree_3d_new(curve_op_data.selected_point_indices.size()); diff --git a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc index 8b653296e12..e739b052b6b 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_deform_curves_on_surface.cc @@ -60,6 +60,7 @@ static void deform_curves(const CurvesGeometry &curves, Array<ReverseUVSampler::Result> surface_samples_old(curves_num); Array<ReverseUVSampler::Result> surface_samples_new(curves_num); threading::parallel_invoke( + 1024 < curves_num, [&]() { reverse_uv_sampler_old.sample_many(curve_attachment_uvs, surface_samples_old); }, [&]() { reverse_uv_sampler_new.sample_many(curve_attachment_uvs, surface_samples_new); }); diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc index 2af86b4b1d2..a5edc6c4b3f 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_line.cc @@ -183,6 +183,7 @@ Mesh *create_line_mesh(const float3 start, const float3 delta, const int count) MutableSpan<MEdge> edges{mesh->medge, mesh->totedge}; threading::parallel_invoke( + 1024 < count, [&]() { threading::parallel_for(verts.index_range(), 4096, [&](IndexRange range) { for (const int i : range) { diff --git a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc index a46bb40a3eb..85facf1e758 100644 --- a/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc +++ b/source/blender/nodes/geometry/nodes/node_geo_mesh_primitive_uv_sphere.cc @@ -307,6 +307,7 @@ static Mesh *create_uv_sphere_mesh(const float radius, const int segments, const MutableSpan<MPoly> polys{mesh->mpoly, mesh->totpoly}; threading::parallel_invoke( + 1024 < segments * rings, [&]() { MutableSpan vert_normals{(float3 *)BKE_mesh_vertex_normals_for_write(mesh), mesh->totvert}; calculate_sphere_vertex_data(verts, vert_normals, radius, segments, rings); |