What is a CPU register?

A CPU register is a tiny on-core storage slot that holds values the processor can use in a single cycle; HNSW distance kernels keep accumulators, pointers, and SIMD lanes in registers so each candidate comparison avoids round-trips to cache or RAM.
Created: Updated: 4 min read

A CPU register is a tiny, extremely fast storage slot built into the processor core itself — holding a single value or a short SIMD vector of values — that instructions can read and write in a single cycle without going to cache or main memory.

Where do registers sit relative to cache and RAM?

Think of the memory hierarchy as a pyramid of capacity versus speed. Registers sit at the very top: fewest slots, lowest latency, accessible directly by the arithmetic units. Below them come L1/L2/L3 caches, then DRAM. An add or multiply can only operate on values that are already in registers (or that an instruction encodes as immediates); anything still in cache or RAM must be loaded into a register first. Compilers and hand-written kernels spend a surprising amount of effort deciding which temporary values stay in registers across a loop and which spill back to stack memory when there are not enough registers to go around. Spills are correct but expensive: they turn what could have been pure register traffic into cache traffic again.

HNSW‘s hottest inner work — scoring a candidate vector — is exactly the kind of loop that lives or dies by how well it keeps working values in registers.

How do registers show up inside a vectorized HNSW distance kernel?

A SIMD distance loop loads slices of dimensions into wide vector registers, multiplies and accumulates in those registers, and only at the end reduces the partial sums into a scalar distance held in a general-purpose or floating-point register before the search compares it to heap thresholds. The query vector’s components are often loaded once and reused from registers (or from L1 with register-held addresses) across many candidate comparisons in the same search step. Neighbor IDs, heap indexes, visited-set hash values, and loop counters occupy scalar registers throughout the traversal. When the compiler can keep the accumulator and pointers in registers for the whole dimension loop, the kernel approaches the arithmetic throughput the SIMD units advertise. When register pressure forces repeated reloads of the same pointer or partial sum from the stack, the measured distance cost rises even though the algorithm did not change.

Register files are also why SIMD width and numeric precision interact so tightly in practice.

Why does register width shape how many dimensions you can process at once?

Each SIMD register has a fixed bit width. Fitting eight 32-bit floats, sixteen 16-bit values, or thirty-two 8-bit values into that same width is what “more lanes at lower precision” means. Vectorized distance computation is therefore not only an algorithm choice but a register-geometry choice: narrower elements increase parallelism inside one register and reduce how many loads are needed for a full vector. Architectures differ in how many such registers a core provides and how many can be live at once before the compiler spills. That is one reason production distance paths — including those used in systems like Weaviate — specialize by instruction set: they are matching the kernel to the register widths and counts available on the chip that will run the search.

Registers do not help with the other half of HNSW time: waiting for the next neighbor’s address to arrive from memory.

When do registers stop mattering compared with memory waits?

During pointer-chasing graph hops, the core often sits idle with plenty of free registers because the next ID or vector base address has not arrived yet. No amount of register renaming fixes a dependent DRAM miss. Registers become the limiting story after data is on-chip: warm distance loops, heap index arithmetic, tight visited-set probes, and the bookkeeping around efSearch stopping conditions. If a profile shows the core compute-bound inside the metric kernel, register-friendly code (few spills, good SIMD utilization, stable query values kept live) is the right polish. If the profile shows memory stalls in traversal, layout and hop count dominate, and staring at register allocation will not move latency much. Knowing which regime you are in keeps optimization effort on the tier of the hierarchy that is actually on the critical path.

A CPU register is the core’s fastest working storage, and HNSW’s distance kernels are written to keep as much of each comparison there as possible. From here, the SIMD and vectorized-distance pages explain how wide registers crush many dimensions at once, the CPU-cache page covers the next tier down when values spill or miss, pointer chasing explains when the core waits despite empty register work, and the CPU-optimization chapter ties register-level kernels to real HNSW speed.