NUMA++ 0.11.0
Loading...
Searching...
No Matches
Memory APIs

NUMA++ memory policy APIs. More...

Topics

 Huge Pages
 Utilities for allocating huge pages.
 

Files

file  memory.hpp
 Contains memory function declarations.
 
file  mempolicy.hpp
 Contains declarations for numapp::MemPolicy.
 
file  memory.cpp
 Definition of memory functions from <numapp/memory.hpp>
 

Classes

class  numapp::PageResource
 Polymorphic memory resource allocating full system pages with specified NUMA policy. More...
 
class  numapp::LockResource
 Lock memory allocated from upstream memory resource using specified LockFlag. More...
 
class  numapp::MemPolicy
 Class representing a memory policy that can be modified and used to apply to the current thread or a memory range. More...
 
class  numapp::ScopedMemPolicy
 Applies memory policy to this thread at construction and reverts to previous at destruction. More...
 

Enumerations

enum class  numapp::MemPolicyFlag : unsigned
 Flag that modify the behaviour of applying a memory policy to a range of memory.
 

Memory Locking

These functions provide the means to prevent memory from being paged to the swap area.

Note
Care should be taken when using these as resident memory consumption will increase as the risk of out-of-memory scenarios. In particular it should be noted that applications may allocate memory that is never resident in normal use. Forcing this memory to be faulted-in may lead to significant memory pressure. One way to avoid that is to use LockFlag::OnFault and LockAllFlag::OnFault which will lock resident memory only. For real-time applications this should not be used however as page faults should be avoided in those scenarios.
Permissions

Locking may require additional permissions if it exceeds resource limits (- getrlimit(2)). Permissions can be provided by CAP_IPC_LOCK (- capabilities(7)).

See also page section Memory Locking.

enum class  numapp::LockFlag : unsigned int { numapp::LockFlag::PreFault = 0u , numapp::LockFlag::OnFault = MLOCK_ONFAULT }
 Mutually exclusive flags that modifies behaviour of MemLock(). More...
 
enum class  numapp::LockAllFlag : int { numapp::LockAllFlag::Current = MCL_CURRENT , numapp::LockAllFlag::Future = MCL_FUTURE , numapp::LockAllFlag::OnFault = MCL_ONFAULT }
 Flags that are combined to modify behaviour of MemLockAll(). More...
 
std::error_code numapp::MemLock (void const *addr, std::size_t len, LockFlag flag) noexcept
 Lock memory pages in the specified address range.
 
std::error_code numapp::MemUnlock (void const *addr, std::size_t len) noexcept
 Unlock memory pages in the specified address range.
 
std::error_code numapp::MemLockAll (LockAllFlag flags) noexcept
 Lock all memory pages as specified by provided flags.
 
std::error_code numapp::MemUnlockAll () noexcept
 Unlock all locked memory in this process.
 

Hardware Queries

Query host system/hardware.

std::size_t numapp::GetPageSize () noexcept
 Fast query of system page size.
 
int numapp::GetNumNodes () noexcept
 Query number of configured NUMA nodes.
 
std::optional< int > numapp::GetNodeDistance (int node1, int node2) noexcept
 Get NUMA distance between two nodes.
 
std::optional< int > numapp::GetNodeOfCpu (int cpu) noexcept
 Get NUMA node of the given CPU.
 

Allocate and free memory with specified memory policy

Allocate
numapp.Allocate() function is equivalent to performing the following:
  • Create new memory mapping with mmap (anonymous read/write) memory
  • Applying memory policy to allocated memory using provided policy and flag (1) using mbind.

(1) Overloads without flag use no modifiers (i.e. won't move pages).

Important
Memory is not pre-faulted by default. If memory is used by real-time threads consider using numapp.MemLock() after allocation to guarantee that pages as faulted in.
However if process locks memory when it is mapped (as controlled by numapp.MemLockAll() with numapp.LockAllFlag.Future) memory may have to be moved to apply the requested policy. It is in this case the flags argument has an important role to control if pages should be moved.
Free
numapp.Free() frees memory previously allocated with numapp.Allocate().
Parameters
[in]sizeNumber of bytes to allocate/free, will be rounded up to multiples of system page size.
[in]policyMemory policy to apply.
[in]flagsControls behaviour if memory have to be moved because it was already paged-in due to a numapp.MemLockAll policy.
[in]ptrPage-aligned pointer to memory previously allocated with numapp.Allocate().
[out]ecError code for non-throwing overloads. If there is an out of memory situation the error code std::errc::not_enough_memory is used.
Exceptions
std::system_erroron failure (only applicable to throwing-overloads without std::error_code return value).
Returns
numapp.Allocate() returns pointer to memory block that is at least size big or nullptr on failure.

Example allocating with bind policy and then lock and pre-fault the newly allocated memory:

void* BindAlloc(std::size_t size, int node, std::error_code& ec) {
using namespace numapp;
void* ptr = Allocate(size, policy, MemPolicyFlag::Strict, ec);
if (ec) {
return nullptr;
}
ec = MemLock(ptr, size, LockFlag::PreFault);
if (ec) {
return nullptr;
}
return ptr;
}
Class representing a memory policy that can be modified and used to apply to the current thread or a ...
static MemPolicy MakeBindNode(int node)
Creates a strict policy (using MPOL_BIND) to allocate all memory to the specified node.
std::error_code MemLock(void const *addr, std::size_t len, LockFlag flag) noexcept
Lock memory pages in the specified address range.
Definition memory.cpp:58
void * Allocate(std::size_t size, MemPolicy const &policy, std::error_code &ec) noexcept
See group for details.
Definition memory.cpp:87
@ PreFault
Locks pages whether they are resident or not.
Definition memory.hpp:126
Contains memory function declarations.
Contains declarations for numapp::MemPolicy.
Related man-page(s):
void * numapp::Allocate (std::size_t size, MemPolicy const &policy, std::error_code &ec) noexcept
 See group for details.
 
void * numapp::Allocate (std::size_t size, MemPolicy const &policy, MemPolicyFlag flags, std::error_code &ec) noexcept
 See group for details.
 
void * numapp::Allocate (std::size_t size, MemPolicy const &policy)
 See group for details.
 
void * numapp::Allocate (std::size_t size, MemPolicy const &policy, MemPolicyFlag flags)
 See group for details.
 
void numapp::Free (void *ptr, std::size_t size, std::error_code &ec) noexcept
 See group for details.
 
void numapp::Free (void *ptr, std::size_t size)
 See group for details.
 
void * Allocate (std::size_t size, MemPolicy const &policy, std::error_code &ec) noexcept
 See group for details.
 
void * Allocate (std::size_t size, MemPolicy const &policy, MemPolicyFlag flags, std::error_code &ec) noexcept
 See group for details.
 
void * Allocate (std::size_t size, MemPolicy const &policy)
 See group for details.
 
void * Allocate (std::size_t size, MemPolicy const &policy, MemPolicyFlag flags)
 See group for details.
 
void Free (void *ptr, std::size_t size, std::error_code &ec) noexcept
 See group for details.
 
void Free (void *ptr, std::size_t size)
 See group for details.
 

Apply Memory Policy to Current Thread

Applies default memory policy to calling thread or to thread stack memory.

std::error_code numapp::thisThread::Apply (MemPolicy const &policy) noexcept
 Applies the default memory policy to the calling thread.
 
std::error_code numapp::thisThread::ApplyStack (MemPolicy const &policy, MemPolicyFlag flags=MemPolicyFlag::Move|MemPolicyFlag::Strict) noexcept
 Convenience function that applies a memory policy to current thread stack memory.
 
std::error_code Apply (MemPolicy const &policy) noexcept
 Applies the default memory policy to the calling thread.
 

Detailed Description

NUMA++ memory policy APIs.

See Memory Policy for an overview.

Enumeration Type Documentation

◆ LockAllFlag

enum class numapp::LockAllFlag : int
strong

Flags that are combined to modify behaviour of MemLockAll().

LockAllFlag have the following operators defined in namespace numapp:

Enumerator
Current 

Lock all pages which are currently mapped into the address space of the process.

Future 

Lock all future pages that are mapped into the address space of the process.

OnFault 

OnFault must be used together with Current and/or Future and modifies the behaviour so pages are not locked until they are faulted in.

Since
Linux 4.4

Definition at line 146 of file memory.hpp.

◆ LockFlag

enum class numapp::LockFlag : unsigned int
strong

Mutually exclusive flags that modifies behaviour of MemLock().

Enumerator
PreFault 

Locks pages whether they are resident or not.

After a successful call to MemLock access to the full range will not trigger page faults.

Note
Behaves like mlock().
OnFault 

Locks currently resident pages as well as future resident pages when they are first faulted in.

Definition at line 119 of file memory.hpp.

Function Documentation

◆ Apply() [1/2]

std::error_code Apply ( MemPolicy const & policy)
related

Applies the default memory policy to the calling thread.

Note
The memory policy is only applied to new physical page allocations.
Parameters
policymemory policy to set.
Related man-page(s):

◆ Apply() [2/2]

std::error_code numapp::thisThread::Apply ( MemPolicy const & policy)
nodiscardnoexcept

Applies the default memory policy to the calling thread.

Note
The memory policy is only applied to new physical page allocations.
Parameters
policymemory policy to set.
Related man-page(s):

◆ ApplyStack()

std::error_code numapp::thisThread::ApplyStack ( MemPolicy const & policy,
MemPolicyFlag flags = MemPolicyFlag::Move|MemPolicyFlag::Strict )
nodiscardnoexcept

Convenience function that applies a memory policy to current thread stack memory.

Note
It relies on pthread API get the stack memory address and size. No pre-faulting is made.
Parameters
policyMemory policy to apply.
flagscombination of MemPolicyFlag values that modify the behaviour. Default is to move pages and fail if this cannot be done.
Related man-page(s):

◆ GetNodeDistance()

std::optional< int > numapp::GetNodeDistance ( int node1,
int node2 )
nodiscardnoexcept

Get NUMA distance between two nodes.

A node has distance 10 to itself.

Parameters
node1NUMA node number.
node2NUMA node number.
Returns
distance between node1 and node2.
std::nullopt when distance cannot be determined.
Related man-page(s):

Definition at line 48 of file memory.cpp.

◆ GetNodeOfCpu()

std::optional< int > numapp::GetNodeOfCpu ( int cpu)
nodiscardnoexcept

Get NUMA node of the given CPU.

Parameters
cpuCPU to get the NUMA node for.
Returns
NUMA node.
std::nullopt if cpu is invalid.
Related man-page(s):

Definition at line 53 of file memory.cpp.

◆ GetNumNodes()

int numapp::GetNumNodes ( )
nodiscardnoexcept

Query number of configured NUMA nodes.

Returns
number of configured NUMA nodes (this also includes any disabled nodes).
Related man-page(s):
  • numa(3) (numa_num_configured_nodes)

Definition at line 44 of file memory.cpp.

◆ GetPageSize()

std::size_t numapp::GetPageSize ( )
nodiscardnoexcept

Fast query of system page size.

Returns
number of bytes in a page.
Related man-page(s):

Definition at line 40 of file memory.cpp.

◆ MemLock()

std::error_code numapp::MemLock ( void const * addr,
std::size_t len,
LockFlag flag )
nodiscardnoexcept

Lock memory pages in the specified address range.

To unlock memory use numapp::MemUnlock or numapp::MemUnlockAll.

Note
Locking memory can be used in conjunction with e.g. numapp::Allocate() to allocate memory and pre-fault it to guarantee that no page-faults happen on subsequent access.
void* buffer = numapp::Allocate(size, policy);
if (std::error_code ec = numapp::MemLock(buffer, size, numapp::LockFlag::PreFault); ec) {
// Handle error
}
Parameters
addrDefines the starting address of the range.
lenDefines the length of the address range.
flagBehaviour modifier, see LockFlag.
Returns
error code populated with errno error.
Related man-page(s):

Definition at line 58 of file memory.cpp.

◆ MemLockAll()

std::error_code numapp::MemLockAll ( LockAllFlag flags)
nodiscardnoexcept

Lock all memory pages as specified by provided flags.

As an example this is how to lock current and future memory allocations:

using namespace numapp; // Also brings in operator| into scope so that flags can be OR-ed.
// Failed to lock...
}
std::error_code MemLockAll(LockAllFlag flags) noexcept
Lock all memory pages as specified by provided flags.
Definition memory.cpp:72
@ Current
Lock all pages which are currently mapped into the address space of the process.
Definition memory.hpp:150
@ Future
Lock all future pages that are mapped into the address space of the process.
Definition memory.hpp:155

To unlock memory use MemUnlock and MemUnlockAll.

Warning
If flag LockAllFlag::Future is used memory pages will be locked during mapping using the calling thread default memory policy. For numapp::Allocate() this means that pages may have to be moved after mapping (see also notes in numapp::Allocate()).
Parameters
flagsCombination of LockAllFlag values. See documentation of LockAllFlag how it modifies the behaviour.
Returns
error code populated with errno error.
Related man-page(s):

Definition at line 72 of file memory.cpp.

◆ MemUnlock()

std::error_code numapp::MemUnlock ( void const * addr,
std::size_t len )
nodiscardnoexcept

Unlock memory pages in the specified address range.

Parameters
addrDefines the starting address of the range.
lenDefines the length of the address range.
Returns
error code populated with errno error.
Related man-page(s):

Definition at line 65 of file memory.cpp.

◆ MemUnlockAll()

std::error_code numapp::MemUnlockAll ( )
nodiscardnoexcept

Unlock all locked memory in this process.

Returns
error code populated with errno error.
Related man-page(s):

Definition at line 79 of file memory.cpp.