Geometry Nodes: Parallelize reading and writing vertex groups

Reading or writing a vertex group is expensive enough that it's worth
parallelizing. On a Ryzen 3700x, in a grid of 250k vertices with
30 randomly assigned vertex groups (each to 10-50% of vertices),
I observed a 4x improvement for writing to a group and a 3x
improvement when reading their data. This significantly speeds
up nodes that create a new mesh from a mesh that had vertex groups.
This commit is contained in:
Hans Goudey 2023-01-04 16:25:01 -05:00
parent 83f519b7c1
commit 224d26fd33
1 changed files with 14 additions and 10 deletions

View File

@ -997,9 +997,11 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
void set_all(Span<float> src) override
{
for (const int64_t index : src.index_range()) {
this->set(index, src[index]);
}
threading::parallel_for(src.index_range(), 4096, [&](const IndexRange range) {
for (const int64_t i : range) {
this->set(i, src[i]);
}
});
}
void materialize(IndexMask mask, MutableSpan<float> r_span) const override
@ -1007,14 +1009,16 @@ class VArrayImpl_For_VertexWeights final : public VMutableArrayImpl<float> {
if (dverts_ == nullptr) {
return r_span.fill_indices(mask, 0.0f);
}
for (const int64_t index : mask) {
if (const MDeformWeight *weight = this->find_weight_at_index(index)) {
r_span[index] = weight->weight;
threading::parallel_for(mask.index_range(), 4096, [&](const IndexRange range) {
for (const int64_t i : mask.slice(range)) {
if (const MDeformWeight *weight = this->find_weight_at_index(i)) {
r_span[i] = weight->weight;
}
else {
r_span[i] = 0.0f;
}
}
else {
r_span[index] = 0.0f;
}
}
});
}
void materialize_to_uninitialized(IndexMask mask, MutableSpan<float> r_span) const override