add comment explaining the use case of cached_alloc

This commit is contained in:
Francisco 2021-05-06 13:47:43 +01:00 committed by Francisco Paisana
parent b619a2b649
commit cd51537234
2 changed files with 18 additions and 10 deletions

View File

@ -20,11 +20,18 @@
namespace srsran { namespace srsran {
/**
* Custom Allocator that caches deallocated memory blocks in a stack to be reused in future allocations.
* This minimizes the number of new/delete calls, when the rate of insertions/removals match (e.g. a queue)
* This allocator is not thread-safe. It assumes the container is being used in a single-threaded environment,
* or being mutexed when altered, which is a reasonable assumption
* @tparam T object type
*/
template <typename T> template <typename T>
class cached_alloc : public std::allocator<T> class cached_alloc : public std::allocator<T>
{ {
struct memblock_t : public intrusive_double_linked_list_element<> { struct memblock_t : public intrusive_double_linked_list_element<> {
memblock_t(size_t sz) : block_size(sz) {} explicit memblock_t(size_t sz) : block_size(sz) {}
size_t block_size; size_t block_size;
}; };
const size_t min_n = (sizeof(memblock_t) + sizeof(T) - 1) / sizeof(T); const size_t min_n = (sizeof(memblock_t) + sizeof(T) - 1) / sizeof(T);

View File

@ -65,33 +65,34 @@ void cached_deque_benchmark()
using std::chrono::high_resolution_clock; using std::chrono::high_resolution_clock;
using std::chrono::microseconds; using std::chrono::microseconds;
srsran::deque<int> my_deque; srsran::queue<int> my_deque;
std::deque<int> std_deque; std::queue<int> std_deque;
high_resolution_clock::time_point tp; high_resolution_clock::time_point tp;
size_t N = 10000000, n_elems = 10; size_t N = 10000000, n_elems = 10;
for (size_t i = 0; i < n_elems; ++i) { for (size_t i = 0; i < n_elems; ++i) {
my_deque.push_back(i); my_deque.push(i);
std_deque.push_back(i); std_deque.push(i);
} }
// NOTE: this benchmark doesnt account for when memory is fragmented // NOTE: this benchmark doesnt account for when memory is fragmented
tp = high_resolution_clock::now(); tp = high_resolution_clock::now();
for (size_t i = n_elems; i < N; ++i) { for (size_t i = n_elems; i < N; ++i) {
std_deque.push_back(i); std_deque.push(i);
std_deque.pop_front(); std_deque.pop();
} }
microseconds t_std = std::chrono::duration_cast<microseconds>(high_resolution_clock::now() - tp); microseconds t_std = std::chrono::duration_cast<microseconds>(high_resolution_clock::now() - tp);
tp = high_resolution_clock::now(); tp = high_resolution_clock::now();
for (size_t i = n_elems; i < N; ++i) { for (size_t i = n_elems; i < N; ++i) {
my_deque.push_back(i); my_deque.push(i);
my_deque.pop_front(); my_deque.pop();
} }
microseconds t_cached = std::chrono::duration_cast<microseconds>(high_resolution_clock::now() - tp); microseconds t_cached = std::chrono::duration_cast<microseconds>(high_resolution_clock::now() - tp);
fmt::print("Time elapsed: cached alloc={} usec, std alloc={} usec", t_cached.count(), t_std.count()); fmt::print("Time elapsed: cached alloc={} usec, std alloc={} usec\n", t_cached.count(), t_std.count());
fmt::print("queue sizes: {} {}\n", my_deque.size(), std_deque.size());
} }
int main() int main()