bytes_ostream: Avoid waste by rounding up allocation size to power-of-two
- bytes_ostream has a default initial chunk size of 512. - let's say we call bytes_ostream::write() to write 500 bytes. - as next_alloc_size() takes into account space to hold chunk metadata (24 bytes) + chunk data, then 512 bytes is not enough, so it returns 500 + 24 instead to be allocated. - when allocating next chunk, next_alloc_size() will use the size of existing chunk, which is 500 bytes (without metadata) and multiply it to 2 (growth factor), so 1000 bytes is allocated for it. So allocations can be non power-of-two, resulting in memory waste. When seastar is allocating from small pools, the waste is not terrible (although accumulated small wastes can be problematic), but once allocations pass the large threshold (16k), then alignment is 4k (page size) and the waste is not negligible. Signed-off-by: Raphael S. Carvalho <raphaelsc@scylladb.com> Closes #11027
This commit is contained in:
committed by
Avi Kivity
parent
a645bb3622
commit
7d97e15c43
@@ -15,6 +15,7 @@
|
||||
#include "hashing.hh"
|
||||
#include <seastar/core/simple-stream.hh>
|
||||
#include <seastar/core/loop.hh>
|
||||
#include <bit>
|
||||
#include <concepts>
|
||||
|
||||
/**
|
||||
@@ -116,12 +117,14 @@ private:
|
||||
// - must be at least _initial_chunk_size
|
||||
// - try to double each time to prevent too many allocations
|
||||
// - should not exceed max_alloc_size, unless data_size requires so
|
||||
// - will be power-of-two so the allocated memory can be fully utilized.
|
||||
size_type next_alloc_size(size_t data_size) const {
|
||||
auto next_size = _current
|
||||
? _current->size * 2
|
||||
: _initial_chunk_size;
|
||||
next_size = std::min(next_size, max_alloc_size());
|
||||
return std::max<size_type>(next_size, data_size + sizeof(chunk));
|
||||
auto r = std::max<size_type>(next_size, data_size + sizeof(chunk));
|
||||
return std::bit_ceil(r);
|
||||
}
|
||||
// Makes room for a contiguous region of given size.
|
||||
// The region is accounted for as already written.
|
||||
|
||||
Reference in New Issue
Block a user