#!/usr/bin/env bash set -euo pipefail # Compare memory efficiency (Max RSS) between HAKMEM and System on tiny-hot bench. # - Runs selected sizes/batches with /usr/bin/time -v and parses Maximum resident set size (KB). # - Optionally toggles HAKMEM_TINY_FLUSH_ON_EXIT to evaluate exit-time trimming. # Output: bench_results/memory_eff_YYYYMMDD_HHMMSS/results.csv # Usage: scripts/run_memory_efficiency.sh [cycles] ROOT_DIR=$(cd "$(dirname "$0")/.." && pwd) cd "$ROOT_DIR" cycles=${1:-60000} if [[ ! -x /usr/bin/time ]]; then echo "[error] /usr/bin/time not found. Install 'time' package." >&2 exit 1 fi echo "[build] perf_main benches (no bench-only macros)" make -s perf_main >/dev/null TS=$(date +%Y%m%d_%H%M%S) OUTDIR="bench_results/memory_eff_${TS}" mkdir -p "$OUTDIR" CSV="$OUTDIR/results.csv" echo "allocator,size,batch,cycles,flush_on_exit,max_rss_kb,elapsed_ms" > "$CSV" sizes=(32 64 128) batches=(100) run_case() { local alloc="$1"; shift local size="$1"; shift local batch="$1"; shift local cyc="$1"; shift local flush="$1"; shift local bin if [[ "$alloc" == "hakmem" ]]; then bin=./bench_tiny_hot_hakmem; else bin=./bench_tiny_hot_system; fi local tmp_log="$OUTDIR/tmp_${alloc}_${size}_${batch}_${cyc}_${flush}.log" local tmp_out="$OUTDIR/tmp_${alloc}_${size}_${batch}_${cyc}_${flush}.out" if [[ "$alloc" == "hakmem" ]]; then HAKMEM_TINY_FLUSH_ON_EXIT="$flush" /usr/bin/time -v "$bin" "$size" "$batch" "$cyc" >"$tmp_out" 2>"$tmp_log" || true else /usr/bin/time -v "$bin" "$size" "$batch" "$cyc" >"$tmp_out" 2>"$tmp_log" || true fi local rss=$(sed -n 's/^\s*Maximum resident set size (kbytes): \([0-9]\+\).*/\1/p' "$tmp_log" | tail -1) local elapsed=$(sed -n 's/^\s*Elapsed (wall clock) time (h:mm:ss or m:ss): \(.*\)/\1/p' "$tmp_log" | tail -1) # convert elapsed to ms (best-effort; handles m:ss or h:mm:ss) local ms=0 if [[ -n "$elapsed" ]]; then local e1="" e2="" e3="" IFS=: read -r e1 e2 e3 <<<"$elapsed" || true if [[ -n "$e3" ]]; then # h:m:s ms=$(( (10#${e1}*3600 + 10#${e2}*60) * 1000 )) ms=$(( ms + (10#${e3%.*})*1000 )) else # m:s ms=$(( (10#${e1}*60) * 1000 )) ms=$(( ms + (10#${e2%.*})*1000 )) fi fi echo "$alloc,$size,$batch,$cyc,$flush,${rss:-},${ms:-}" >> "$CSV" } for s in "${sizes[@]}"; do for b in "${batches[@]}"; do echo "[run] SYSTEM size=$s batch=$b cycles=$cycles" run_case system "$s" "$b" "$cycles" 0 echo "[run] HAKMEM (flush=0) size=$s batch=$b cycles=$cycles" run_case hakmem "$s" "$b" "$cycles" 0 echo "[run] HAKMEM (flush=1) size=$s batch=$b cycles=$cycles" run_case hakmem "$s" "$b" "$cycles" 1 done done echo "[done] CSV: $CSV" sed -n '1,40p' "$CSV" || true