diff options
author | Hans Goudey <h.goudey@me.com> | 2021-05-09 07:57:36 +0300 |
---|---|---|
committer | Hans Goudey <h.goudey@me.com> | 2021-05-09 07:57:36 +0300 |
commit | 518c5ce4cd75aabcc649efb9e118d18622b5ea70 (patch) | |
tree | 081a15e98f11aeb7f30f47fa85d1f66314e4c109 /source/blender/blenkernel | |
parent | b7afb8ea7001e2717f8d3ab38ec2b13f9fdf4587 (diff) |
Geometry Nodes: Improve point instance node performance
This commit uses two changes to improve the performance of the point
instance node.
**Prevent Reallocations**
At 64 bytes, the transform matrix for every instance is rather large,
so reallocating the vector as it grows can become a performance bottle-
neck. This commit reserves memory for the instances that will be added
to prevent unecessary reallocations as the instance vector grows.
In a test with 4 million instances of 3 objects in a collection, the
node was about 40% faster, from 370ms to 270ms for the node.
**Parallelization**
Currently the instances are added by appending to a vector. By changing
this slightly to fill indices instead, we can parallelize the operation
so that multiple threads can fill data at the same time. Tested on a
Ryzen 3700x, this reduced the runtime from the above 270ms to 44ms
average, bringing the total speedup to ~8x.
Note that displaying the instances in the viewport is still much slower
than the calculations in node, this change doesn't affect that.
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_geometry_set.hh | 2 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/geometry_component_instances.cc | 18 |
2 files changed, 20 insertions, 0 deletions
diff --git a/source/blender/blenkernel/BKE_geometry_set.hh b/source/blender/blenkernel/BKE_geometry_set.hh index 106af8172d1..bd2b062152d 100644 --- a/source/blender/blenkernel/BKE_geometry_set.hh +++ b/source/blender/blenkernel/BKE_geometry_set.hh @@ -597,6 +597,7 @@ class InstancesComponent : public GeometryComponent { void clear(); void reserve(int min_capacity); + void resize(int capacity); int add_reference(InstanceReference reference); void add_instance(int instance_handle, const blender::float4x4 &transform, const int id = -1); @@ -604,6 +605,7 @@ class InstancesComponent : public GeometryComponent { blender::Span<InstanceReference> references() const; blender::Span<int> instance_reference_handles() const; + blender::MutableSpan<int> instance_reference_handles(); blender::MutableSpan<blender::float4x4> instance_transforms(); blender::Span<blender::float4x4> instance_transforms() const; blender::MutableSpan<int> instance_ids(); diff --git a/source/blender/blenkernel/intern/geometry_component_instances.cc b/source/blender/blenkernel/intern/geometry_component_instances.cc index 55025ed5ac9..f1294341464 100644 --- a/source/blender/blenkernel/intern/geometry_component_instances.cc +++ b/source/blender/blenkernel/intern/geometry_component_instances.cc @@ -56,6 +56,19 @@ void InstancesComponent::reserve(int min_capacity) instance_ids_.reserve(min_capacity); } +/** + * Resize the transform, handles, and ID vectors to the specified capacity. + * + * \note This function should be used carefully, only when it's guarenteed + * that the data will be filled. + */ +void InstancesComponent::resize(int capacity) +{ + instance_reference_handles_.resize(capacity); + instance_transforms_.resize(capacity); + instance_ids_.resize(capacity); +} + void InstancesComponent::clear() { instance_reference_handles_.clear(); @@ -81,6 +94,11 @@ blender::Span<int> InstancesComponent::instance_reference_handles() const return instance_reference_handles_; } +blender::MutableSpan<int> InstancesComponent::instance_reference_handles() +{ + return instance_reference_handles_; +} + blender::MutableSpan<blender::float4x4> InstancesComponent::instance_transforms() { return instance_transforms_; |