Aligned Allocators (alloc-madvise)
A memory allocator for creating large aligned chunks of memory in an optimal fashion. This library is meant
to be used standalone or via FFI with the original use case being .NET P/Invoke.
Memory is dynamically aligned to the most efficient boundaries based on size,
ensuring that AVX workloads can use use aligned loads and stores. Huge Page support
is automatically enabled based on the allocation size. If the flag for sequential access is provided,
memory will be m-advised for fast scans rather than random accesses; clearing out
the memory is optional.
fn main() {
const TWO_MEGABYTES: usize = 2 * 1024 * 1024;
const SIZE: usize = TWO_MEGABYTES * 2;
const SEQUENTIAL: bool = true;
const CLEAR: bool = true;
let memory = Memory::allocate(SIZE, SEQUENTIAL, CLEAR)
.expect("allocation failed");
assert_ne!(memory.address, std::ptr::null_mut());
assert_eq!((memory.address as usize) % TWO_MEGABYTES, 0);
let data: &mut [f32] = memory.as_mut();
data[0] = 1.234;
data[1] = 5.678;
let reference: &[f32] = memory.as_ref();
assert_eq!(reference[0], 1.234);
assert_eq!(reference[1], 5.678);
assert_eq!(reference[2], 0.0);
assert_eq!(reference.len(), memory.len() / std::mem::size_of::<f32>());
}
Build
cargo build --release
To strip object files in order to create a smaller library, run e.g.
strip target/release/liballoc_madvise.so
Note that future Cargo version will have an option of stripping debug symbols.
C/C++ FFI
For the FFI, the library is built in both dylib and staticlib flavors.
Building the crate auto-generates a header file containing the declarations:
#include <cstdarg>
#include <cstdint>
#include <cstdlib>
#include <ostream>
#include <new>
namespace ffi {
struct Memory {
uint32_t status;
uint32_t flags;
uint32_t num_bytes;
void *address;
};
extern "C" {
const char *version();
Memory allocate_block(uint32_t num_bytes, bool sequential, bool clear);
void free_block(Memory memory);
}
}