2026-09-10
For 25 years, if you needed a serializing instruction on x86 — one that forces the CPU to retire every prior instruction and flush every prefetch buffer before continuing — you had exactly one portable option: CPUID. It was a hack. CPUID's job is feature discovery, and it clobbers EAX, EBX, ECX, and EDX every time you invoke it. Using it as a pipeline barrier meant saving and restoring four general-purpose registers you didn't actually want to read.
Intel added SERIALIZE (opcode 0F 01 E8) in Ice Lake server / Sapphire Rapids, and AMD added it in Zen 4. It is a one-byte-name instruction that does exactly one thing: serialize the instruction stream. No operands, no register outputs, no memory effects — just a pipeline drain.
Why do you need this? Three real cases:
SERIALIZE; RDTSC gives you a start timestamp that no earlier instruction can slip past. Previously you'd use CPUID; RDTSC and pay 200+ cycles plus register spills.Cost rule of thumb: SERIALIZE retires in roughly 50–80 cycles on Sapphire Rapids when the pipeline is lightly loaded — versus 200–350 cycles for CPUID leaf 0. Add the cost of the register save/restore around CPUID and you're looking at a 4–5x speedup for the common "I just need a barrier" case.
Concrete example — reading a PMU counter you just enabled:
wrmsr; push rax..rdx; xor eax,eax; cpuid; pop rdx..rax; rdpmcwrmsr; serialize; rdpmcTwo gotchas: First, SERIALIZE does not imply a memory fence. It drains the instruction pipeline, but stores in the store buffer may not be globally visible when it retires — you still need MFENCE if you care about memory ordering. Second, check CPUID.(EAX=7,ECX=0):ECX bit 14 before using it; on pre-Ice Lake hardware the opcode raises #UD.
