AlignedAllocator#

#include <hpk/alignedAllocator.hpp>

The AlignedAllocator class is an Allocator that provides cacheline-aligned memory, which is recommended for performance reasons.

This header file also defines the free functions allocateMemory() and allocateScratch(), which by default use an AlignedAllocator to provide memory that is managed by a std::unique_ptr.

This is a header-only implementation.


CLASS

template<class T, std::size_t align = hardware_constructive_interference_size>
struct AlignedAllocator#

An allocator that provides aligned memory.

AlignedAllocator allocates memory using std::aligned_alloc and satisfies the C++ named requirements for an Allocator.

The default alignment is std::hardware_constructive_interference_size if that is defined; otherwise, 64 bytes.

Examples:

// Construct a std::vector whose data is (the default) 64B-aligned and
// initialize it with 10 floats of value 0.0f.  (Note that the type of
// v1 is not std::vector<float>, as that uses std::allocator.)
auto v1 = std::vector<float, hpk::AlignedAllocator<float>>(10);

// Construct an empty std::vector whose data will be 32B-aligned.
// (Note that the types of v1 and v2 are not the same.)
auto v2 = std::vector<float, hpk::AlignedAllocator<float, 32>>();

Public Types

using value_type = T#

T, a cv-unqualified object type

Public Functions

inline constexpr AlignedAllocator() noexcept#

Default constructor.

template<class U>
inline constexpr AlignedAllocator(const AlignedAllocator<U, align>&) noexcept#

Copy constructor.

inline T *allocate(std::size_t n) const#

Allocates uninitialized storage suitable for an array object of type T.

Allocates aligned memory for n elements of type T, but does not construct array elements. If n == 0, returns nullptr. If allocation fails and exceptions are enabled, an exception is thrown. If allocation fails and exceptions are disabled (e.g., by a compiler flag), then nullptr is returned.

inline void deallocate(T *p, std::size_t) const noexcept#

Deallocates storage pointed to by p, which was a value returned by a previous call to allocate().

Note that this does not call the destructor of the object pointed to by p.

template<class L, std::size_t alignL, class R, std::size_t alignR>
constexpr bool operator==(const AlignedAllocator<L, alignL>&, const AlignedAllocator<R, alignR>&) noexcept#

Returns true. The storage allocated by any AlignedAllocator can be deallocated through another one, regardless of template parameters.

template<class L, std::size_t alignL, class R, std::size_t alignR>
constexpr bool operator!=(const AlignedAllocator<L, alignL>&, const AlignedAllocator<R, alignR>&) noexcept#

Returns false.

template<class U>
struct rebind#

FUNCTIONS

template<typename T, class Allocator = AlignedAllocator<T>>
auto hpk::allocateMemory(std::size_t n, Allocator &&alloc = Allocator())#

Allocates memory for n elements of type T

More specifically, the return value is a std::unique_ptr<T, hpk::Deleter<Allocator>>. If Allocator is not specified, hpk::AlignedAllocator<T> is the default. Note that T must be trivially destructible (e.g., a non-class type compatible with the C language).

Examples:

// Allocate (the default) 64B-aligned memory for 10 floats.
auto tmp1 = hpk::allocateMemory<float>(10);

// Allocate 8B-aligned memory for 20 floats.
auto tmp2 =
    hpk::allocateMemory<float, hpk::AlignedAllocator<float, 8>>(20);

// Allocate memory for 30 floats using the standard allocator.
auto tmp3 = hpk::allocateMemory<float, std::allocator<float>>(30);

// Use an instance to allocate 128B-aligned memory for 40 doubles.
hpk::AlignedAllocator<double, 128> alloc;
auto tmp4 = hpk::allocateMemory<double>(40, alloc);

Returns:

std::unique_ptr that owns the allocated memory.

template<typename ...Args, typename std::enable_if_t<std::conjunction_v<uses_scratch<Args>...>, int> = 0>
auto hpk::allocateScratch(const Args&... args)#

Allocates scratch memory for any of the compute arguments.

This function finds the maximum of each compute object’s scratchSize() and then allocates scratch memory using the default AlignedAllocator.

Example:

// Given three pointers to FFT compute objects, the following
// allocates scratch memory which is suitable for any of them:
auto scratch = hpk::allocateScratch(*fft1, *fft2, *fft3);

Returns:

std::unique_ptr that owns the allocated memory.

template<typename Arg, typename ...Args, typename std::enable_if_t<std::disjunction_v<is_allocator<Args>...> && uses_scratch_v<Arg>, int> = 0>
auto hpk::allocateScratch(Arg &&arg, Args&&... args)#

Allocates scratch memory for any of the compute arguments using the Allocator that is supplied as the final argument.

This function finds the maximum of each compute object’s scratchSize() and then allocates scratch memory using an Allocator instance.

Example:

// Given three pointers to double precision compute objects, the
// following allocates scratch memory suitable for any of them:
hpk::AlignedAllocator<double> alloc;
auto scratch = hpk::allocateScratch(*fft1, *fft2, *fft3, alloc);

Returns:

std::unique_ptr that owns the allocated memory.