mirror of https://github.com/PentHertz/srsLTE.git
add comment explaining the use case of cached_alloc
This commit is contained in:
parent
b619a2b649
commit
cd51537234
|
@ -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);
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue