diff --git a/lib/include/srsran/adt/pool/cached_alloc.h b/lib/include/srsran/adt/pool/cached_alloc.h index aa4e24fb9..64ac1f531 100644 --- a/lib/include/srsran/adt/pool/cached_alloc.h +++ b/lib/include/srsran/adt/pool/cached_alloc.h @@ -20,11 +20,18 @@ 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 class cached_alloc : public std::allocator { 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; }; const size_t min_n = (sizeof(memblock_t) + sizeof(T) - 1) / sizeof(T); diff --git a/lib/test/adt/cached_alloc_test.cc b/lib/test/adt/cached_alloc_test.cc index 737bd368f..4ef63b4a8 100644 --- a/lib/test/adt/cached_alloc_test.cc +++ b/lib/test/adt/cached_alloc_test.cc @@ -65,33 +65,34 @@ void cached_deque_benchmark() using std::chrono::high_resolution_clock; using std::chrono::microseconds; - srsran::deque my_deque; - std::deque std_deque; + srsran::queue my_deque; + std::queue std_deque; high_resolution_clock::time_point tp; size_t N = 10000000, n_elems = 10; for (size_t i = 0; i < n_elems; ++i) { - my_deque.push_back(i); - std_deque.push_back(i); + my_deque.push(i); + std_deque.push(i); } // NOTE: this benchmark doesnt account for when memory is fragmented tp = high_resolution_clock::now(); for (size_t i = n_elems; i < N; ++i) { - std_deque.push_back(i); - std_deque.pop_front(); + std_deque.push(i); + std_deque.pop(); } microseconds t_std = std::chrono::duration_cast(high_resolution_clock::now() - tp); tp = high_resolution_clock::now(); for (size_t i = n_elems; i < N; ++i) { - my_deque.push_back(i); - my_deque.pop_front(); + my_deque.push(i); + my_deque.pop(); } microseconds t_cached = std::chrono::duration_cast(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()