C.1-8Vector Examples I: Add, Masks, SAXPY, SGEMM, Estimates

Part III Linux boot: optional Vol. I (Unprivileged) pp. 650–657 · ~2 min read

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.

The example kernels (§C.1-C.8)
What it demonstrates
C.1 vvaddint32The canonical strip-mine loop: vsetvli → vle → vadd → vse → advance by vl → branch. The template every vector loop follows.
C.2 mixed-width mask+computeHolding 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 memcpyByte strip-mining at LMUL=m8 — the widest strips for a pure-bandwidth copy.
C.4 conditionalVectorizing an “if”: compare into a mask, then run the operation under v0.t — predication replaces the branch.
C.5 SAXPYy = a·x + y via vfmacc.vf — scalar a broadcast, one fused multiply-add per element. The archetypal BLAS-1 kernel.
C.6 SGEMMThe production example: register-blocked tiled matrix multiply, accumulating a tile of C in vector registers across the k loop.
C.7 / C.8 reciprocal & rsqrtvfrec7 / vfrsqrt7 seed + Newton-Raphson refinement — the estimate-then-iterate pattern for divide and inverse-sqrt.
Dotted-underlined cells have explanations — click one.

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'?

3 questions