Spin-wait loops burn power re-checking a flag that hasn’t changed.
PAUSE hints that the hart’s retirement rate should drop for a
bounded (possibly zero) time — saving energy, and on SMT cores
lending execution resources to sibling harts. Linux’s
cpu_relax() is exactly this.
Usage rules: one PAUSE per loop iteration in portable code (its duration legitimately ranges from zero to ~a memory access, so stacking oversleeps on some cores); a run of PAUSEs gives a roughly proportional delay when you do control the target. And because it occupies FENCE encoding space, PAUSE inside an LR/SC sequence voids the forward-progress guarantee — spin on a plain load, PAUSE, and only then retry the LR.
Hardware Designer Notes
Implement the simple version: a decode-stage counter that inhibits issue for a few dozen cycles. It’s one of the highest value-per-gate features on this page’s tier — every futex, every qspinlock, every ticket lock in Linux spins through cpu_relax().
Minimal Linux-boot hart MUST
- Decode 0x0100000F as at minimum a no-op — a fence with an empty successor set already orders nothing
MAY simplify / trap-and-emulate
- Stall retirement for a fixed ~10-100 cycle window, gate the issue stage, or drop thread priority in SMT — any bounded slowdown conforms
- Drain the store buffer first (the FENCE-space privilege) so the sibling hart sees the spin variable update sooner
Check yourself — PAUSE
1.Why is PAUSE encoded inside the FENCE opcode (pred=W, succ=∅) rather than as an integer no-op HINT?
2.How should a portable spin-wait loop use PAUSE?