"Zihintpause": The PAUSE Hint

Part III Linux boot: recommended Vol. I (Unprivileged) p. 59 · ~2 min read

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.

fm=00003128pred=W2724succ=∅2320rs1=x019150001412rd=x0117000111160PAUSE = FENCE pred=W, succ=∅ (0x0100000F)
Click a field for its role.

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?

2 questions