Add bn::base::SegmentedVector#8289
Conversation
|
having benchmarked this on my branch, it immediately cuts about 40% of allocations related to instruction storage and will be useful in tons of other places, so in favor of merging and then pointing it towards those asap. I've only checked it with the fixed size 128 chunks, and it's probably worth exploring a few others (32->128 geometric might be a further optimization, but fixed-128 is already ~93% efficient). |
|
@bdash did you say there were som eunit tests that went along with this? |
|
Yes, on the branch of the same name in the internal repository. |
|
Seems like there may be a potential inconsistency. bulk_construct ensures we're less than max_size but the other reserve, emplace_ back and push_ back do not. |
| // Total element slots across all currently allocated chunks. | ||
| size_type capacity() const noexcept { return chunk_base(m_directory.size()); } | ||
|
|
||
| void reserve(size_type n) |
There was a problem hiding this comment.
Should this check max_size similar to bulk_construct?
| std::destroy_at(&m_directory); | ||
| std::construct_at(&m_directory, std::move(newDir)); | ||
|
|
||
| append_range(other.begin(), other.end()); |
There was a problem hiding this comment.
Can append_range throw here after modifying *this? If so, you could possibly create a SegmentedVector tmp(other, other.m_alloc, CopyTag{}); at the top which moves the throwing bit before the *this modification.
A back-growing segmented array, consisting of a directory of pointers to geometrically sized chunks. It gives portable, controlled chunk sizing (unlike
std::deque), O(1) random access, and a guarantee that growth never moves, copies, or reallocates existing elements.Chunk capacities follow a geometric ramp (
B,2B,4B, ...,C) and then a fixed plateau (C,C,C, ...), whereBisInitialChunkElemsandCisMaxChunkElems, both powers of two. A 0 means "use the byte-budget default forT", which gives three usage modes: