Adding a benchmark
Existing benchmarks: Dhrystone, CoreMark, MicroBench. Adding a new one means a new test kernel + a measurement entry in the perf pipeline.
Kernel
Create a new directory under xkernels/tests/benchmark/<name>/:
xkernels/tests/benchmark/<name>/
├── Makefile # uses xam/scripts/build_c.mk or build_rs.mk
├── src/
│ └── main.c # or .rs — the benchmark itself
└── README.md # what it measures, expected score range
The Makefile should delegate to xam's build system. Link against
xlib for printf / memcpy.
Exit via the SiFive test finisher:
#include <klib.h>
extern void xam_halt(int code);
int main() {
uint64_t t0 = uptime();
/* ... work ... */
uint64_t t1 = uptime();
printf("score = %lu\n", compute_score(t1 - t0));
xam_halt(0);
return 0;
}
Measurement pipeline
Add the new benchmark to scripts/perf/bench.sh so CI / manual
runs capture it:
BENCHES=(dhrystone coremark microbench <name>)
Also teach scripts/perf/sample.sh how to capture its sample
profile (usually the same per-workload path).
Baseline
After landing:
- Run
bash scripts/perf/bench.sh --runs 3. This writes the new workload intodocs/perf/baselines/<today>/data/bench.csv. - Run
bash scripts/perf/sample.shto produce the sample traces. - Run
python3 scripts/perf/render.pyfor the SVG flamegraphs. - Commit the new
data/+graphics/files.
Reporting in PROGRESS.md
Add a row to the "Benchmark" table in the project root README.md
if the benchmark is user-facing enough to publish. Update
../PROGRESS.md §Phase 9 if the workload
introduces a new cost centre worth tracking per-phase.
Performance hygiene
- Don't add a benchmark that depends on wall-clock non-determinism (interrupt timing, stdin blocking). Use deterministic work loops.
- Use
uptime()(microseconds) for in-guest timing; it's derived from ACLINT mtime, which is frozen during xdb pause. - Take 3 runs for the published number;
user_sis the stable metric.