|
template<typename D = T, typename J = I, typename B = A, std::enable_if_t<!std::is_same< B, std::nullptr_t >::value > * = nullptr> |
| Atomics_array (A &alloc, size_t size, T init_value) |
| Constructor allowing a specific memory allocator, a specific queue size and the instance of T to initialize the array with. More...
|
|
template<typename D = T, typename J = I, typename B = A, std::enable_if_t< std::is_same< B, std::nullptr_t >::value > * = nullptr> |
| Atomics_array (size_t size, T init_value) |
| Constructor allowing a specific queue size and the instance of T to initialize the array with. More...
|
|
| Atomics_array (Atomics_array< T, I, A > const &rhs)=delete |
|
| Atomics_array (Atomics_array< T, I, A > &&rhs)=delete |
|
virtual | ~Atomics_array ()=default |
| Destructor for the class. More...
|
|
Atomics_array< T, I, A > & | operator= (Atomics_array< T, I, A > const &rhs)=delete |
|
Atomics_array< T, I, A > & | operator= (Atomics_array< T, I, A > &&rhs)=delete |
|
element_type & | operator[] (size_t index) const |
| Retrieves the value stored in a specific index of the array. More...
|
|
Iterator | begin () const |
| Retrieves an iterator instance that points to the beginning of the array. More...
|
|
Iterator | end () const |
| Retrieves an iterator instance that points to the end of the underlying array. More...
|
|
template<typename Pred > |
std::tuple< T, size_t > | find_if (Pred predicate, size_t start_from=0) const |
| Finds a value in the queue according to the evaluation of predicate by traversing the array from start_from to the array size. More...
|
|
size_t | find (T to_find, size_t start_from=0) const |
| First the first occurrence of to_find , starting at start_from index. More...
|
|
size_t | size () const |
| Returns the size of the array. More...
|
|
size_t | allocated_size () const |
| Returns the number of bytes used to allocate the array. More...
|
|
std::string | to_string () const |
| Return this queue textual representation. More...
|
|
template<typename T, typename I = container::Padded_indexing<T>, typename A = std::nullptr_t>
class container::Atomics_array< T, I, A >
Array of std::atomic
elements of type T
.
An array of std::atomic
elements implies, almost for sure, a multi-threaded environment and concurrent access to the array may lead to false sharing when consecutive elements are pulled into the same CPU cache line. This class accepts, as a template parameter, a helper class that is both an element storage index translator and element storage size provider. Different strategies to prevent false sharing and the subsequent cache invalidation and misses, may be applied. Amongst others, padding each element of the array to the size of the cache line or use index translation to interleave sequential indexes to leave enough space for them not to be pulled into the same cache line. The two described strategies are provided already with the container::Padded_indexing
and container::Interleaved_indexing
classes.
Template parameters are as follows:
T
: the integral type for the array elements.
I
: type of indexing to be used by this array in the form of a class. Available classes are container::Padded_indexing
and container::Interleaved_indexing
. The parameter defaults to container::Padded_indexing
.
A
: type of memory allocator to be used, in the form of a class (defaults to no allocator).
When and if deciding between interleaved or padded indexing, one could take into consideration, amongst possibly others, the following arguments:
- For arrays with random concurrent access patterns, interleaved indexing doesn't ensure false-sharing prevention.
- For arrays with sequential concurrent access patterns, if it's needed that interleaved indexing prevents false-sharing, consecutive array indexes will need to be apart, physically, the size of a cache-line. So, in a system with expectation of T threads accessing concurrently an array of elements of size
E
and with a cache-line of size CL
, the array capacity should be at least T * (CL / E)
for interleaved indexing to prevent false-sharing.
- Padded indexing will always prevent false-sharing but it will consume more memory in order to have the same array capacity as the interleaved indexing.
template<typename T , typename I , typename A >
template<typename D , typename J , typename B , std::enable_if_t<!std::is_same< B, std::nullptr_t >::value > * >
Constructor allowing a specific memory allocator, a specific queue size and the instance of T
to initialize the array with.
- Parameters
-
alloc | The memory allocator instance |
size | The desired size for the queue |
init_value | The instance of T to initialize the array with |
template<typename T , typename I , typename A >
template<typename Pred >
Finds a value in the queue according to the evaluation of predicate
by traversing the array from start_from
to the array size.
The find condition is given according to the predicate predicate
which should be any predicate which translatable to [](value_type value, size_t index) -> bool
. If the predicate evaluates to true
, the value and respective index are returned as an std::tuple
.
Check C++ documentation for the definition of Predicate
named requirement for more information.
- Parameters
-
predicate | The predicate to be evaluated |
start_from | The index to start the search at |
- Returns
- A tuple holding the value and the index of the first element for which the predicate evaluated to true. If the predicate doesn't evaluate to true for any of the elements, it returns a pair holding the default value for
T
and the size of the array.