The spec’s own worked vector kernels — the best way to see the strip-mining idiom, masking, and FMA loops in motion. All non-normative, all illustrative.
| What it demonstrates | |
|---|---|
| C.1 vvaddint32 | The canonical strip-mine loop: vsetvli → vle → vadd → vse → advance by vl → branch. The template every vector loop follows. |
| C.2 mixed-width mask+compute | Holding SEW/LMUL constant across widths so a mask made at one width gates a compute at another (the element-map alignment from ch. 31.4). |
| C.3 memcpy | Byte strip-mining at LMUL=m8 — the widest strips for a pure-bandwidth copy. |
| C.4 conditional | Vectorizing an “if”: compare into a mask, then run the operation under v0.t — predication replaces the branch. |
| C.5 SAXPY | y = a·x + y via vfmacc.vf — scalar a broadcast, one fused multiply-add per element. The archetypal BLAS-1 kernel. |
| C.6 SGEMM | The production example: register-blocked tiled matrix multiply, accumulating a tile of C in vector registers across the k loop. |
| C.7 / C.8 reciprocal & rsqrt | vfrec7 / vfrsqrt7 seed + Newton-Raphson refinement — the estimate-then-iterate pattern for divide and inverse-sqrt. |
The SAXPY loop distilled — the shape to memorize:
saxpy:
vsetvli a4, a0, e32, m8, ta, ma # vl = this strip
vle32.v v0, (a1) # load x strip
sub a0, a0, a4 # n -= vl
slli a4, a4, 2 # vl * 4 bytes
add a1, a1, a4 # advance x
vle32.v v8, (a2) # load y strip
vfmacc.vf v8, fa0, v0 # y = a*x + y (a in fa0)
vse32.v v8, (a2) # store y
add a2, a2, a4 # advance y
bnez a0, saxpy
ret
Hardware Designer Notes
For a vector-unit designer, these are your first performance targets. If SAXPY doesn’t saturate memory bandwidth and SGEMM doesn’t saturate the FMA units, the microarchitecture has a bottleneck the ISA didn’t impose. The strcmp and fractional-LMUL examples continue on the next page.
Minimal Linux-boot hart MUST
- Nothing new — these validate the V extension already specified. They are the software the hardware must run correctly
MAY simplify / trap-and-emulate
- Use these kernels as microbenchmarks: vvaddint32 and memcpy for bandwidth, SAXPY/SGEMM for FMA throughput, C.7/C.8 for the estimate-refine latency chain
- Verify the estimate instructions against these NR sequences — the seed tables are normative, so the refined results must match
Check yourself — vector code examples
1.SAXPY (y = a·x + y) uses LMUL=m8 and vfmacc.vf. Why the wide LMUL and the .vf form?
2.The division and square-root approximation examples (C.7, C.8) use vfrec7/vfrsqrt7 followed by more instructions. Why not just one instruction?
3.What does the conditional example (C.4) demonstrate about vectorizing an 'if'?