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 30 additions and 5 deletions
Showing only changes of commit 5b9f8cd9f5 - Show all commits

View File

@ -26,6 +26,16 @@ inline const std::array<int16_t, max_chunk_size> &get_static_indices_array()
return data; return data;
} }
inline int64_t index_to_chunk_index(const int64_t i)
{
return i >> chunk_size_shift;
}
inline int64_t size_to_chunk_num(const int64_t size)
{
return (size + max_chunk_size - 1) >> chunk_size_shift;
}
const IndexMask &get_static_index_mask_for_min_size(const int64_t min_size); const IndexMask &get_static_index_mask_for_min_size(const int64_t min_size);
struct ChunkIteratorData { struct ChunkIteratorData {
@ -126,14 +136,29 @@ inline IndexMask::IndexMask()
inline IndexMask::IndexMask(const int64_t size) inline IndexMask::IndexMask(const int64_t size)
{ {
*this = get_static_index_mask_for_min_size(size); *this = get_static_index_mask_for_min_size(size);
data_.chunks_num = (size + max_chunk_size - 1) >> chunk_size_shift; data_.chunks_num = size_to_chunk_num(size);
data_.end_it.index_in_segment = size & chunk_mask_low; data_.end_it.index_in_segment = size & chunk_mask_low;
} }
inline IndexMask IndexMask::slice(const IndexRange range) const inline IndexMask::IndexMask(const IndexRange range)
{ {
IndexMask sliced_mask = *this; if (range.is_empty()) {
return sliced_mask; return;
}
*this = get_static_index_mask_for_min_size(range.one_after_last());
const int64_t first_chunk_i = index_to_chunk_index(range.first());
const int64_t last_chunk_i = index_to_chunk_index(range.last());
data_.chunks_num = last_chunk_i - first_chunk_i + 1;
data_.indices_num = range.size();
data_.chunks -= first_chunk_i;
data_.chunk_offsets -= first_chunk_i;
data_.chunk_sizes_cumulative -= first_chunk_i;
data_.begin_it.segment_index = 0;
data_.begin_it.index_in_segment = range.first() & chunk_mask_low;
data_.end_it.segment_index = 0;
data_.end_it.index_in_segment = range.one_after_last() & chunk_mask_low;
} }
inline const IndexMaskData &IndexMask::data() const inline const IndexMaskData &IndexMask::data() const

View File

@ -10,7 +10,7 @@ namespace blender::index_mask::tests {
TEST(index_mask2, Test) TEST(index_mask2, Test)
{ {
IndexMask mask(3); IndexMask mask(IndexRange(16000, 1000));
mask.foreach_index_span([&](const int64_t offset, const Span<int16_t> indices) { mask.foreach_index_span([&](const int64_t offset, const Span<int16_t> indices) {
for (const int64_t i : indices) { for (const int64_t i : indices) {
std::cout << (i + offset) << "\n"; std::cout << (i + offset) << "\n";