fastmem API reference Changelog View on GitHub

API reference

Fast memory operations using native SIMD vectors.

memcpy and memmove now live in separate modules so their policy decisions can diverge cleanly, while still sharing the low-level load/store primitives and the overlap-safe forward kernel.

pub const impl = …

src
value
.{
    .copy = copy_impl_name,
    .move = move_impl_name,
    .set = set_impl_name,
}

Names of the kernel implementations in this build, one per operation. Dispatch names identify the stub family and any selected experiment. dispatch.kernelName identifies the selected level and its move policy.

struct dispatch

src

Runtime CPU dispatch. It is active in x86_64 Linux builds whose target CPU lacks AVX2, when build.zig links the level objects. enabled is false in every other build, and the functions then return null or error.Unsupported.

Constants

pub const enabled = on_dispatch

src

True when this build dispatches: an x86_64 Linux target without AVX2, with the level objects that build.zig links into the fastmem module.

pub const small_max = x86_dispatch.small_max

src

Sizes up to this bound never consult the dispatcher, on any path.

Functions

pub fn level() ?Level

src

The level of the kernels. The first use selects it from CPUID.

pub fn kernelName() ?[:0]const u8

src

The kernel implementation name of the level, as impl names it in a comptime build for that CPU.

pub fn detect() ?Info

src

The CPUID and XCR0 facts that the selection reads.

pub fn force(l: Level) error{Unsupported}!void

src

Use l instead of the detected level: a test hook. The CPU must support the level. It compiles only in fastmem's own test modules: the public module never sets the x86_test_hooks option.

Types

enum Level

src
pub const Level = x86_dispatch.Level

Fields

generic generic

The generic Zig kernels, compiled for the consumer CPU.

x86_64_v3 x86_64_v3

The AVX2 kernels. Also the 32-byte-vector row of tuning.zig for Skylake-SP, Cascade Lake, and Ice Lake.

x86_64_v4 x86_64_v4

The AVX-512 kernels without model tuning: no REP, no NT stores.

sapphirerapids sapphirerapids
graniterapids graniterapids
znver4 znver4
znver5 znver5

Functions

pub fn requires(level: Level) Isa

src

The CPU features that the kernel object of this level requires.

struct Info

src
pub const Info = x86_dispatch.Info

Fields

vendor: Vendor
family: u32

The display family and model (base plus extended fields).

model: u32
features: Mask

Functions

pub fn decode(raw: Raw) Info

src

pub fn has(info: Info, isa: Isa) bool

src

pub fn supports(info: Info, level: Level) bool

src

pub fn select(info: Info) Level

src

pub inline fn copy(comptime T: type, dest: []T, source: []const T) void

src

pub inline fn move(comptime T: type, dest: []T, source: []const T) void

src

pub inline fn set(comptime T: type, dest: []T, value: T) void

src

Fill dest with value. Prefer over @memset for runtime-sized fills.

The byte kernels are bit-pattern fills: they apply to T == u8, or to any T with a unique in-memory representation whose value bytes are all equal (checked at runtime; comptime-known for u8). Every other type takes the element-wise fallback loop.

pub fn exportSymbols() void

src

Export strong, hidden memcpy, memmove, and memset for this link unit. Call it from the program that owns the final link, never from a library that another program imports: the definitions would join every consumer's link and collide with the consumer's own symbols.

struct abi

src

C-ABI entry points with the libc signatures, each returning dest. The entries receive libc names only after exportSymbols. The benchmark measures these as fastmem_abi. Dedicated kernels handle aarch64 and AVX2. x86_64 Linux builds without AVX2 get the runtime-dispatch entries: 0 to 128 bytes inline, larger sizes through the dispatcher. Other targets use generic Zig wrappers.

Constants

pub const memcpy: LibcCopyFn = …

src
value
if (on_x86)
        &x86_move.kernel
    else if (on_dispatch)
        &x86_dispatch.memcpy
    else if (on_aarch64)
        libc_copy_fn
    else
        &generic.memcpy

pub const memmove: LibcCopyFn = …

src
value
if (on_x86)
        &x86_move.moveKernel
    else if (on_dispatch)
        &x86_dispatch.memmove
    else if (on_aarch64)
        libc_move_fn
    else
        &generic.memmove

pub const memset: LibcSetFn = …

src
value
if (on_x86)
        &x86_set.kernel
    else if (on_dispatch)
        &x86_dispatch.memset
    else if (on_aarch64)
        libc_set_fn
    else
        &generic.memset