BLI: refactor IndexMask for better performance and memory usage #104629

Merged
Jacques Lucke merged 254 commits from JacquesLucke/blender:index-mask-refactor into main 2023-05-24 18:11:47 +02:00
2 changed files with 17 additions and 17 deletions
Showing only changes of commit 6b6f0b7267 - Show all commits

View File

@ -42,7 +42,7 @@ struct RawMaskIterator {
struct Chunk {
int16_t segments_num;
const int16_t **indices_by_segment;
const int16_t *segment_sizes_cumulative;
const int16_t *cumulative_segment_sizes;
RawChunkIterator end_iterator() const;
OffsetIndices<int16_t> segment_offsets() const;
@ -273,7 +273,7 @@ inline RawChunkIterator Chunk::index_to_iterator(const int16_t index) const
BLI_assert(index < this->segment_offsets().total_size());
RawChunkIterator it;
it.segment_i = this->segment_offsets().find_range_index(index);
it.index_in_segment = index - this->segment_sizes_cumulative[it.segment_i];
it.index_in_segment = index - this->cumulative_segment_sizes[it.segment_i];
return it;
}
@ -283,7 +283,7 @@ inline int16_t Chunk::iterator_to_index(const RawChunkIterator &it) const
BLI_assert(it.segment_i < this->segments_num);
BLI_assert(it.index_in_segment >= 0);
BLI_assert(it.index_in_segment < this->segment_offsets().size(it.segment_i));
return this->segment_sizes_cumulative[it.segment_i] + it.index_in_segment;
return this->cumulative_segment_sizes[it.segment_i] + it.index_in_segment;
}
/* -------------------------------------------------------------------- */
@ -433,18 +433,18 @@ inline RawChunkIterator Chunk::end_iterator() const
inline OffsetIndices<int16_t> Chunk::segment_offsets() const
{
return Span<int16_t>(this->segment_sizes_cumulative, this->segments_num + 1);
return Span<int16_t>(this->cumulative_segment_sizes, this->segments_num + 1);
}
inline int16_t Chunk::size() const
{
return this->segment_sizes_cumulative[this->segments_num + 1] -
this->segment_sizes_cumulative[0];
return this->cumulative_segment_sizes[this->segments_num + 1] -
this->cumulative_segment_sizes[0];
}
inline int16_t Chunk::segment_size(const int16_t segment_i) const
{
return this->segment_sizes_cumulative[segment_i + 1] - this->segment_sizes_cumulative[segment_i];
return this->cumulative_segment_sizes[segment_i + 1] - this->cumulative_segment_sizes[segment_i];
}
template<typename Fn> inline void IndexMask::foreach_raw_segment(Fn &&fn) const
@ -469,10 +469,10 @@ template<typename Fn> inline void IndexMask::foreach_raw_segment(Fn &&fn) const
const bool is_last_chunk = (chunk_i == data_.chunks_num - 1);
const int16_t segments_num = is_last_chunk ? final_segments_num : chunk.segments_num;
const int64_t offset = chunk_capacity + chunk_id;
int16_t prev_cumulative_segment_size = chunk.segment_sizes_cumulative[segment_i];
int16_t prev_cumulative_segment_size = chunk.cumulative_segment_sizes[segment_i];
while (segment_i < segments_num) {
const int16_t next_segment_i = segment_i + 1;
const int16_t cumulative_segment_size = chunk.segment_sizes_cumulative[next_segment_i];
const int16_t cumulative_segment_size = chunk.cumulative_segment_sizes[next_segment_i];
const int16_t stored_segment_size = cumulative_segment_size - prev_cumulative_segment_size;
const bool is_last_segment = is_last_chunk & (segment_i == final_segment_i);
const int16_t segment_drop_back = is_last_segment * final_drop_back;

View File

@ -33,14 +33,14 @@ const IndexMask &get_static_index_mask_for_min_size(const int64_t min_size)
static Array<int64_t> chunk_sizes_cumulative(chunks_num + 1);
static const int16_t *static_offsets = get_static_indices_array().data();
static const int16_t static_segment_sizes_cumulative[2] = {0, chunk_capacity};
static const int16_t static_cumulative_segment_sizes[2] = {0, chunk_capacity};
threading::parallel_for(IndexRange(chunks_num), 1024, [&](const IndexRange range) {
for (const int64_t i : range) {
Chunk &chunk = chunks_array[i];
chunk.segments_num = 1;
chunk.indices_by_segment = &static_offsets;
chunk.segment_sizes_cumulative = static_segment_sizes_cumulative;
chunk.cumulative_segment_sizes = static_cumulative_segment_sizes;
chunk_ids_array[i] = i;
chunk_sizes_cumulative[i] = i * chunk_capacity;
@ -229,7 +229,7 @@ template<typename T> IndexMask to_index_mask(const Span<T> indices, ResourceScop
index_allocations_num);
MutableSpan<const int16_t *> remaining_indices_by_segment =
allocator.allocate_array<const int16_t *>(segments_in_chunks.size());
MutableSpan<int16_t> remaining_segment_sizes_cumulative = allocator.allocate_array<int16_t>(
MutableSpan<int16_t> remaining_cumulative_segment_sizes = allocator.allocate_array<int16_t>(
segments_in_chunks.size() + slice.size());
const OffsetIndices<int64_t> segments_by_chunk = segments_per_chunk_cumulative.as_span();
@ -242,13 +242,13 @@ template<typename T> IndexMask to_index_mask(const Span<T> indices, ResourceScop
MutableSpan<const int16_t *> indices_by_segment = take_front_and_drop(
remaining_indices_by_segment, segments_num);
MutableSpan<int16_t> segment_sizes_cumulative = take_front_and_drop(
remaining_segment_sizes_cumulative, segments_num + 1);
MutableSpan<int16_t> cumulative_segment_sizes = take_front_and_drop(
remaining_cumulative_segment_sizes, segments_num + 1);
int64_t cumulative_size = 0;
for (const int64_t segment_i : IndexRange(segments_num)) {
const RangeOrSpanVariant<T> &segment = segments_in_chunks[segments_in_chunk[segment_i]];
segment_sizes_cumulative[segment_i] = int16_t(cumulative_size);
cumulative_segment_sizes[segment_i] = int16_t(cumulative_size);
if (std::holds_alternative<IndexRange>(segment)) {
const IndexRange range_in_segment = std::get<IndexRange>(segment);
@ -268,10 +268,10 @@ template<typename T> IndexMask to_index_mask(const Span<T> indices, ResourceScop
cumulative_size += indices_in_segment.size();
}
}
segment_sizes_cumulative[segments_num] = int16_t(cumulative_size);
cumulative_segment_sizes[segments_num] = int16_t(cumulative_size);
chunk.indices_by_segment = indices_by_segment.data();
chunk.segment_sizes_cumulative = segment_sizes_cumulative.data();
chunk.cumulative_segment_sizes = cumulative_segment_sizes.data();
}
});