06 — Writing a New Level (optim15)¶
This tutorial shows how to add a new optimization level to the ladder. We'll add
src/matvec/optim15.c as a concrete example.
The pattern for a new level¶
Every level is a self-contained program that:
- does
#include <matvec.h>(or<gemm.h>), - defines its kernel function (here
matvec), - has a
main()that fills data, times the kernel, and prints GFLOPS.
1. Write the source¶
Create src/matvec/optim15.c, copying the structure of optim14.c (the current best
portable level) and changing the kernel. For example, a 4× reduce-unrolled, packed,
register kernel:
#include <matvec.h>
#define A(i,j) a[(j)*lda+(i)]
void matvec(int m, int k, double *a, int lda, double *x, double *y){
for (int i = 0; i < m; i += 4){
double c0=0,c1=0,c2=0,c3=0;
for (int p = 0; p < k; p += 4){
c0 += A(0,p)*x[p]; c1 += A(1,p)*x[p];
c2 += A(2,p)*x[p]; c3 += A(3,p)*x[p];
c0 += A(0,p+1)*x[p+1]; c1 += A(1,p+1)*x[p+1];
c2 += A(2,p+1)*x[p+1]; c3 += A(3,p+1)*x[p+1];
c0 += A(0,p+2)*x[p+2]; c1 += A(1,p+2)*x[p+2];
c2 += A(2,p+2)*x[p+2]; c3 += A(3,p+2)*x[p+2];
c0 += A(0,p+3)*x[p+3]; c1 += A(1,p+3)*x[p+3];
c2 += A(2,p+3)*x[p+3]; c3 += A(3,p+3)*x[p+3];
}
y[i] += c0; y[i+1] += c1; y[i+2] += c2; y[i+3] += c3;
}
}
int main(void){
/* copy the main() from optim14.c: fill random data, time matvec(...),
print seconds and GFLOPS */
return 0;
}
Copy main() from src/matvec/optim14.c and update the printed label to
Optimization 15.
2. Make it build¶
The Makefile auto-discovers matvec levels by name. Because optim15 is covered by
the matvec% pattern rule, it builds automatically:
If it doesn't, add 15 to MATVEC_LEVELS in the Makefile.
3. Document the mathematics¶
Create docs/research/matvec/optim15.md following the style of the other research
notes: the math of the operation, the memory/stride analysis, the ILP story, a FLOP
accounting, and a summary table.
4. Add a tutorial (optional)¶
If your level demonstrates a genuinely new technique, add a short section to an
existing tutorial or create a new tutorial page, and register any new nav page in
mkdocs.yml.
5. Verify¶
And confirm the level still gives identical results to the reference — the ladder is about speed, never about changing the answer.
Tip
Want to fix the gap for x86? Sponsor a portable sse_compat.h so matmul
optim11–14 compile on Apple Silicon too — see the research notes for what
SSR/AVX intrinsics they expect.