perf_callgrind.sh (2940B)
1 #!/usr/bin/env bash 2 # perf_callgrind.sh — measure kit's retired-instruction (`Ir`) cost compiling 3 # sqlite3.c under Linux callgrind, the campaign's instruction metric (PERF.md §3). 4 # macOS has no valgrind, so this runs inside an arm64 Linux container (podman). 5 # 6 # Codifies the recipe documented in doc/plan/PERF.md §3, including its gotchas: 7 # (a) -lc so kit finds the glibc sysroot; bookworm (glibc 2.36) not ubuntu. 8 # (b) strip --strip-debug in place before profiling (valgrind 3.19 vs DWARF5). 9 # (c) trust self/exclusive Ir, not inclusive (recursion double-counts). 10 # 11 # Usage: 12 # scripts/perf_callgrind.sh image # one-time: build the kit-prof image (apt deps baked in) 13 # scripts/perf_callgrind.sh run [TAG] # build kit in-container, run callgrind, annotate 14 # # writes build/linux-prof/cg.<TAG>.out + cg.<TAG>.annot.txt 15 # # prints the total Ir 16 # scripts/perf_callgrind.sh total TAG # print the total Ir for a prior run 17 set -eu 18 19 PLATFORM="${KIT_PROF_PLATFORM:-linux/arm64}" 20 IMG="${KIT_PROF_IMAGE:-kit-prof}" 21 BASE="docker.io/arm64v8/debian:bookworm-slim" 22 ROOT="$(cd "$(dirname "$0")/.." && pwd)" 23 OUTDIR="$ROOT/build/linux-prof" 24 25 cmd="${1:-run}" 26 27 case "$cmd" in 28 image) 29 # Bake the apt deps into a reusable image so repeated runs skip apt-get. 30 podman rm -f kitprof-base >/dev/null 2>&1 || true 31 podman run --name kitprof-base --platform "$PLATFORM" "$BASE" sh -c ' 32 set -eu; export DEBIAN_FRONTEND=noninteractive 33 apt-get update -qq && apt-get install -y -qq clang lld make libc6-dev binutils valgrind perl' 34 podman commit kitprof-base "$IMG" 35 podman rm kitprof-base >/dev/null 36 echo "built image: $IMG" 37 ;; 38 run) 39 TAG="${2:-head}" 40 mkdir -p "$OUTDIR" 41 podman run --rm --platform "$PLATFORM" -v "$ROOT":/work:Z "$IMG" sh -c " 42 set -eu 43 cd /work 44 make bin RELEASE=1 PROFILE=1 CC=clang AR=ar BUILD_DIR=build/linux-prof >/work/build/linux-prof/build.$TAG.log 2>&1 45 strip --strip-debug build/linux-prof/kit 46 cd tmp/projects/sqlite-amalg 47 valgrind --tool=callgrind --cache-sim=no --branch-sim=no --dump-instr=no \ 48 --collect-jumps=no --callgrind-out-file=/work/build/linux-prof/cg.$TAG.out \ 49 /work/build/linux-prof/kit cc -c sqlite3.c -lc -o /tmp/k.o 2>/work/build/linux-prof/cg.$TAG.vg.log 50 callgrind_annotate --threshold=99.5 /work/build/linux-prof/cg.$TAG.out > /work/build/linux-prof/cg.$TAG.annot.txt 2>/dev/null 51 " 52 tot="$(grep -m1 'PROGRAM TOTALS' "$OUTDIR/cg.$TAG.annot.txt" | grep -oE '^[0-9,]+' | tr -d ',')" 53 echo "TAG=$TAG total Ir = ${tot:-?} (annot: build/linux-prof/cg.$TAG.annot.txt)" 54 ;; 55 total) 56 TAG="${2:?usage: total TAG}" 57 grep -m1 'PROGRAM TOTALS' "$OUTDIR/cg.$TAG.annot.txt" | grep -oE '^[0-9,]+' | tr -d ',' 58 ;; 59 *) 60 echo "usage: $0 {image|run [TAG]|total TAG}" >&2; exit 2;; 61 esac