timemory 3.3.0
Modular C++ Toolkit for Performance Analysis and Logging. Profiling API and Tools for C, C++, CUDA, Fortran, and Python. The C++ template API is essentially a framework to creating tools: it is designed to provide a unifying interface for recording various performance measurements alongside data logging and interfaces to other tools.
tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV > Class Template Reference

allocator that uses array of (ring) buffers to coalesce memory. Requires This allocator propagates on container swap and container move assignment. Use TIMEMORY_RING_BUFFER_ALLOCATOR_BUFFER_COUNT env variable to specify the default number of allocations or use the set_buffer_count / set_buffer_count_cb. When a reserve is requested and the request is greater than the free spaces in the buffer, the free spaces are stored in a "dangling" array of spaces which are used when single allocations are requested. More...

#include "timemory/data/ring_buffer_allocator.hpp"

+ Collaboration diagram for tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >:

Classes

struct  rebind
 

Public Types

using value_type = Tp
 
using pointer = Tp *
 
using reference = Tp &
 
using const_pointer = const Tp *
 
using const_reference = const Tp &
 
using size_type = size_t
 
using difference_type = ptrdiff_t
 
using base_type = std::allocator< Tp >
 
using buffer_type = data_storage::ring_buffer< Tp >
 
using propagate_on_container_move_assignment = std::true_type
 
using propagate_on_container_swap = std::true_type
 

Public Member Functions

 ring_buffer_allocator ()=default
 
 ~ring_buffer_allocator ()=default
 
 ring_buffer_allocator (const ring_buffer_allocator &)=default
 
 ring_buffer_allocator (ring_buffer_allocator &&) noexcept=default
 
ring_buffer_allocatoroperator= (const ring_buffer_allocator &)=default
 
ring_buffer_allocatoroperator= (ring_buffer_allocator &&) noexcept=default
 
bool operator== (const ring_buffer_allocator &rhs) const
 
bool operator!= (const ring_buffer_allocator &rhs) const
 
Tp * address (Tp &_r) const
 
const Tp * address (const Tp &_r) const
 
size_t max_size () const
 
void construct (Tp *const _p, const Tp &_v) const
 
void construct (Tp *const _p, Tp &&_v) const
 
template<typename... ArgsT>
void construct (Tp *const _p, ArgsT &&... _args) const
 
void destroy (Tp *const _p) const
 
Tp * allocate (const size_t n) const
 
void deallocate (Tp *const ptr, const size_t n) const
 
Tp * allocate (const size_t n, const void *const) const
 
void reserve (const size_t n)
 
void steal_resources (ring_buffer_allocator &rhs)
 transfers the buffers to another allocator More...
 

Static Public Member Functions

template<typename FuncT >
static void set_buffer_count_cb (FuncT &&_f)
 define a callback function for initializing the buffer size. Will throw if a request for the buffer size has already occured. More...
 
static void set_buffer_count (size_t _buff_sz)
 set the minimum number of objects for the ring buffer. Will throw if a request for the buffer size has already occured. More...
 

Detailed Description

template<typename Tp, bool MMapV, size_t BuffCntV>
class tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >

allocator that uses array of (ring) buffers to coalesce memory. Requires This allocator propagates on container swap and container move assignment. Use TIMEMORY_RING_BUFFER_ALLOCATOR_BUFFER_COUNT env variable to specify the default number of allocations or use the set_buffer_count / set_buffer_count_cb. When a reserve is requested and the request is greater than the free spaces in the buffer, the free spaces are stored in a "dangling" array of spaces which are used when single allocations are requested.

Template Parameters
TpThe data type for the allocator
MMapVWhether to use mmap (if available)
BuffCntVThe default buffer count (will be rounded up to multiple of page size)

Definition at line 57 of file ring_buffer_allocator.hpp.


Class Documentation

◆ tim::data::ring_buffer_allocator::rebind

struct tim::data::ring_buffer_allocator::rebind
template<typename Tp, bool MMapV, size_t BuffCntV>
template<typename U>
struct tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::rebind< U >

Definition at line 99 of file ring_buffer_allocator.hpp.

+ Collaboration diagram for tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::rebind< U >:
Class Members
typedef ring_buffer_allocator< U, MMapV, BuffCntV > other

Member Typedef Documentation

◆ base_type

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::base_type = std::allocator<Tp>

Definition at line 68 of file ring_buffer_allocator.hpp.

◆ buffer_type

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::buffer_type = data_storage::ring_buffer<Tp>

Definition at line 69 of file ring_buffer_allocator.hpp.

◆ const_pointer

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::const_pointer = const Tp*

Definition at line 64 of file ring_buffer_allocator.hpp.

◆ const_reference

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::const_reference = const Tp&

Definition at line 65 of file ring_buffer_allocator.hpp.

◆ difference_type

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::difference_type = ptrdiff_t

Definition at line 67 of file ring_buffer_allocator.hpp.

◆ pointer

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::pointer = Tp*

Definition at line 62 of file ring_buffer_allocator.hpp.

◆ propagate_on_container_move_assignment

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::propagate_on_container_move_assignment = std::true_type

Definition at line 70 of file ring_buffer_allocator.hpp.

◆ propagate_on_container_swap

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::propagate_on_container_swap = std::true_type

Definition at line 71 of file ring_buffer_allocator.hpp.

◆ reference

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::reference = Tp&

Definition at line 63 of file ring_buffer_allocator.hpp.

◆ size_type

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::size_type = size_t

Definition at line 66 of file ring_buffer_allocator.hpp.

◆ value_type

template<typename Tp , bool MMapV, size_t BuffCntV>
using tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::value_type = Tp

Definition at line 61 of file ring_buffer_allocator.hpp.

Constructor & Destructor Documentation

◆ ring_buffer_allocator() [1/3]

template<typename Tp , bool MMapV, size_t BuffCntV>
tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::ring_buffer_allocator ( )
default

◆ ~ring_buffer_allocator()

template<typename Tp , bool MMapV, size_t BuffCntV>
tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::~ring_buffer_allocator ( )
default

◆ ring_buffer_allocator() [2/3]

template<typename Tp , bool MMapV, size_t BuffCntV>
tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::ring_buffer_allocator ( const ring_buffer_allocator< Tp, MMapV, BuffCntV > &  )
default

◆ ring_buffer_allocator() [3/3]

template<typename Tp , bool MMapV, size_t BuffCntV>
tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::ring_buffer_allocator ( ring_buffer_allocator< Tp, MMapV, BuffCntV > &&  )
defaultnoexcept

Member Function Documentation

◆ address() [1/2]

template<typename Tp , bool MMapV, size_t BuffCntV>
const Tp * tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::address ( const Tp &  _r) const
inline

Definition at line 89 of file ring_buffer_allocator.hpp.

89{ return &_r; }

◆ address() [2/2]

template<typename Tp , bool MMapV, size_t BuffCntV>
Tp * tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::address ( Tp &  _r) const
inline

Definition at line 88 of file ring_buffer_allocator.hpp.

88{ return &_r; }

◆ allocate() [1/2]

template<typename Tp , bool MMapV, size_t BuffCntV>
Tp * tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::allocate ( const size_t  n) const
inline

Definition at line 116 of file ring_buffer_allocator.hpp.

117 {
118 if(n == 0)
119 return nullptr;
120
121 // integer overflow check that throws std::length_error in case of overflow
122 if(n > max_size())
123 {
124 throw std::length_error(
125 "ring_buffer_allocator<Tp>::allocate() - Integer overflow.");
126 }
127
128 // for a single allocation, try to reuse dangling allocations
129 if(n == 1 && !m_buffer_data->dangles.empty())
130 {
131 Tp* _p = m_buffer_data->dangles.back();
132 m_buffer_data->dangles.pop_back();
133 return _p;
134 }
135
136 // ensure m_buffer_data->current is assigned and a buffer has been created
137 init_current(n);
138
139 // when n is greater than the remainder of the ring buffer allocation,
140 // add the remainder of the allocation to the dangling allocations and
141 // then reinitialize current with n to ensure that the memory is contiguous
142 if(n > m_buffer_data->current->free())
143 {
144 m_buffer_data->dangles.reserve(m_buffer_data->dangles.size() +
145 m_buffer_data->current->free());
146 for(size_t i = 0; i < m_buffer_data->current->free(); ++i)
147 {
148 auto _req = m_buffer_data->current->request();
149 if(_req)
150 break;
151 m_buffer_data->dangles.emplace_back(_req);
152 }
153 // ensure a new buffer is created
154 m_buffer_data->current = nullptr;
155 // new buffer will have at least n pages of contiguous memory
156 init_current(n);
157 }
158
159 // get first entry
160 auto* _p = m_buffer_data->current->request();
161
162 // ensure that extra remainder is marked as used by ring buffer
163 for(size_t i = 1; i < n; ++i)
164 m_buffer_data->current->request();
165
166 return _p;
167 }

References tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::max_size().

Referenced by tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::allocate().

◆ allocate() [2/2]

template<typename Tp , bool MMapV, size_t BuffCntV>
Tp * tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::allocate ( const size_t  n,
const void * const   
) const
inline

Definition at line 182 of file ring_buffer_allocator.hpp.

183 {
184 return allocate(n);
185 }

References tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::allocate().

◆ construct() [1/3]

template<typename Tp , bool MMapV, size_t BuffCntV>
template<typename... ArgsT>
void tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::construct ( Tp *const  _p,
ArgsT &&...  _args 
) const
inline

Definition at line 109 of file ring_buffer_allocator.hpp.

110 {
111 ::new((void*) _p) Tp{ std::forward<ArgsT>(_args)... };
112 }
std::array< char *, 4 > _args

References tim::_args.

◆ construct() [2/3]

template<typename Tp , bool MMapV, size_t BuffCntV>
void tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::construct ( Tp *const  _p,
const Tp &  _v 
) const
inline

Definition at line 104 of file ring_buffer_allocator.hpp.

104{ ::new((void*) _p) Tp{ _v }; }

◆ construct() [3/3]

template<typename Tp , bool MMapV, size_t BuffCntV>
void tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::construct ( Tp *const  _p,
Tp &&  _v 
) const
inline

Definition at line 106 of file ring_buffer_allocator.hpp.

106{ ::new((void*) _p) Tp{ std::move(_v) }; }

◆ deallocate()

template<typename Tp , bool MMapV, size_t BuffCntV>
void tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::deallocate ( Tp *const  ptr,
const size_t  n 
) const
inline

Definition at line 169 of file ring_buffer_allocator.hpp.

170 {
171 // reserve if n > 1
172 if(n > 1)
173 m_buffer_data->dangles.reserve(m_buffer_data->dangles.size() + n);
174 // place all "deallocated" pointers in dangling array
175 for(size_t i = 0; i < n; ++i)
176 {
177 Tp* _p = ptr + i;
178 m_buffer_data->dangles.emplace_back(_p);
179 }
180 }

◆ destroy()

template<typename Tp , bool MMapV, size_t BuffCntV>
void tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::destroy ( Tp *const  _p) const
inline

Definition at line 114 of file ring_buffer_allocator.hpp.

114{ _p->~Tp(); }

◆ max_size()

template<typename Tp , bool MMapV, size_t BuffCntV>
size_t tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::max_size ( ) const
inline

Definition at line 91 of file ring_buffer_allocator.hpp.

92 {
93 // avoid signed/unsigned warnings independent of size_t definition
94 return (static_cast<size_t>(0) - static_cast<size_t>(1)) / sizeof(Tp);
95 }

Referenced by tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::allocate().

◆ operator!=()

template<typename Tp , bool MMapV, size_t BuffCntV>
bool tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::operator!= ( const ring_buffer_allocator< Tp, MMapV, BuffCntV > &  rhs) const
inline

Definition at line 85 of file ring_buffer_allocator.hpp.

85{ return (this != &rhs); }

◆ operator=() [1/2]

template<typename Tp , bool MMapV, size_t BuffCntV>
ring_buffer_allocator & tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::operator= ( const ring_buffer_allocator< Tp, MMapV, BuffCntV > &  )
default

◆ operator=() [2/2]

template<typename Tp , bool MMapV, size_t BuffCntV>
ring_buffer_allocator & tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::operator= ( ring_buffer_allocator< Tp, MMapV, BuffCntV > &&  )
defaultnoexcept

◆ operator==()

template<typename Tp , bool MMapV, size_t BuffCntV>
bool tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::operator== ( const ring_buffer_allocator< Tp, MMapV, BuffCntV > &  rhs) const
inline

Definition at line 84 of file ring_buffer_allocator.hpp.

84{ return (this == &rhs); }

◆ reserve()

template<typename Tp , bool MMapV, size_t BuffCntV>
void tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::reserve ( const size_t  n)
inline

Definition at line 187 of file ring_buffer_allocator.hpp.

187{ init_current(n); }

◆ set_buffer_count()

template<typename Tp , bool MMapV, size_t BuffCntV>
static void tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::set_buffer_count ( size_t  _buff_sz)
inlinestatic

set the minimum number of objects for the ring buffer. Will throw if a request for the buffer size has already occured.

Definition at line 201 of file ring_buffer_allocator.hpp.

202 {
203 set_buffer_count_cb([_buff_sz]() { return _buff_sz; });
204 }
static void set_buffer_count_cb(FuncT &&_f)
define a callback function for initializing the buffer size. Will throw if a request for the buffer s...

References tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::set_buffer_count_cb().

◆ set_buffer_count_cb()

template<typename Tp , bool MMapV, size_t BuffCntV>
template<typename FuncT >
static void tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::set_buffer_count_cb ( FuncT &&  _f)
inlinestatic

define a callback function for initializing the buffer size. Will throw if a request for the buffer size has already occured.

Definition at line 192 of file ring_buffer_allocator.hpp.

193 {
194 if(BuffCntV > 0 || get_config_data().initialized)
195 throw std::runtime_error("Error! Buffer size has already been fixed");
196 get_config_data().buffer_count_cb = std::forward<FuncT>(_f);
197 }

Referenced by tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::set_buffer_count().

◆ steal_resources()

template<typename Tp , bool MMapV, size_t BuffCntV>
void tim::data::ring_buffer_allocator< Tp, MMapV, BuffCntV >::steal_resources ( ring_buffer_allocator< Tp, MMapV, BuffCntV > &  rhs)
inline

transfers the buffers to another allocator

Definition at line 207 of file ring_buffer_allocator.hpp.

208 {
209 m_buffer_data->buffers.reserve(m_buffer_data->buffers.size() +
210 rhs.m_buffer_this.buffers.size());
211 m_buffer_data->dangles.reserve(m_buffer_data->dangles.size() +
212 rhs.m_buffer_this.dangles.size());
213 for(auto& itr : rhs.m_buffer_this.buffers)
214 m_buffer_data->buffers.emplace_back(std::move(itr));
215 for(auto& itr : rhs.m_buffer_this.dangles)
216 m_buffer_data->dangles.emplace_back(itr);
217 if(m_buffer_data->current == nullptr)
218 m_buffer_data->current = rhs.m_buffer_this.current;
219 rhs.m_buffer_data = m_buffer_data;
220 }

The documentation for this class was generated from the following file: