BLI: refactor IndexMask for better performance and memory usage #104629
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in New Issue