Memory Alignment
Overview
This document describes the memory alignment guarantees and implementation in the NLAP codebase.
Memory Allocation and Alignment
Default Alignment with malloc
The MemoryManager class uses malloc for memory allocation, which provides the following alignment guarantees:
Standard Guarantee:
mallocreturns memory aligned toalignof(max_align_t)- On x86_64 systems: typically 16 bytes - On x86 systems: typically 8 bytes - This is sufficient for all standard types including atomic typesAlignment Requirements for Common Types: -
char: 1 byte -uint16_t: 2 bytes -uint32_t: 4 bytes -atomic_uint16_t: typically 2 bytes (same asuint16_t) -atomic_uint32_t: typically 4 bytes (same asuint32_t)Why malloc is Sufficient: -
mallocalignment (16 bytes on x86_64) exceeds all requirements - No custom alignment is needed for the types used in this project - Atomic operations work correctly with malloc-allocated memory
Compile-Time Alignment
The MemoryManager template class provides compile-time alignment information:
template<class T>
class MemoryManager {
// Compile-time alignment constant
static constexpr size_t Alignment = alignof(T);
// Get alignment requirement at compile-time
static constexpr size_t getAlignment() {
return Alignment;
}
};
Benefits:
Zero runtime overhead for alignment queries
Enables compile-time optimizations
Type-safe alignment checking
Runtime Alignment Verification
In debug builds, alignment is verified at allocation time:
#if defined(DEBUG_BUILD)
// Verify alignment in debug builds
verifyAlignment();
#endif
This helps catch alignment issues during development without impacting production performance.
Alignment Checking Utilities
The MemoryManager provides static methods for alignment checking:
// Check if a pointer is properly aligned for type T
static bool isAligned(const void* ptr) {
return reinterpret_cast<uintptr_t>(ptr) % Alignment == 0;
}
When std::align is NOT Needed
std::align is primarily useful for:
Creating multiple sub-objects with different alignment requirements in a buffer
Manual memory management with over-aligned types
Implementing custom allocators
In the NLAP codebase:
malloc already provides sufficient alignment
Each MemoryManager instance manages a single type T
No over-aligned types are used
Therefore, std::align is not necessary
Hugepage Support
The code uses madvise(ptr, size, MADV_HUGEPAGE) to request transparent hugepage support:
madvise(MemoryBaseAddress, MemSizeBytes, MADV_HUGEPAGE);
Benefits:
Reduced TLB misses for large memory allocations
Improved performance for memory-intensive operations
Does not affect alignment (hugepages are more strictly aligned)
Testing
Memory alignment is verified through unit tests in test/unit/memory-alignment/:
Default malloc alignment: Verifies
mallocprovidesmax_align_talignmentMemoryManager alignment: Tests alignment for various types (
char,uint16_t,atomic<uint16_t>)Segment pointer alignment: Ensures all segment pointers maintain proper alignment
Atomic type alignment: Verifies atomic types have correct alignment