Files
hakmem/benchmarks/scripts/utils/run_larson.sh

171 lines
4.7 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
set -euo pipefail
# Reproducible larson runner for hakmem/system/mimalloc.
#
# Usage:
# scripts/run_larson.sh [runtime_sec] [threads]
# Examples:
# scripts/run_larson.sh # default: 10s, threads=1 4
# scripts/run_larson.sh 10 1 # 10s, 1 thread
#
# Optional env vars:
# HAKMEM_WRAP_TINY=0|1
# HAKMEM_WRAP_TINY_REFILL=0|1
# HAKMEM_TINY_MAG_CAP=INT
# HAKMEM_SAFE_FREE=0|1
# HAKMEM_EVO_SAMPLE=INT (0 disables evo recording; default 0)
# MIMALLOC_SO=/path/to/libmimalloc.so.2 (optional; if not set, auto-detect)
usage() {
cat << USAGE
Usage: scripts/run_larson.sh [options] [runtime_sec] [threads_csv]
Options:
-d SECONDS Runtime seconds (default: 10)
-t CSV Threads CSV, e.g. 1,4 (default: 1,4)
-c NUM Chunks per thread (default: 10000)
-r NUM Rounds (default: 1)
-m BYTES Min size (default: 8)
-M BYTES Max size (default: 1024)
-s SEED Random seed (default: 12345)
-p PRESET Preset: burst|loop (sets -c/-r)
-w Include WRAP_TINY=1 runs (default: off)
-h Show this help
Env overrides (alternative to flags):
MIN, MAX, CHUNK_PER_THREAD, ROUNDS, SEED
HAKMEM_* toggles per README
USAGE
}
# Defaults
RUNTIME="10"
THREADS_ARG="1,4"
# Workload defaults (burst preset)
MIN="${MIN:-8}"
MAX="${MAX:-1024}"
CHUNK_PER_THREAD="${CHUNK_PER_THREAD:-10000}"
ROUNDS="${ROUNDS:-1}"
SEED="${SEED:-12345}"
PRESET=""
INCLUDE_WRAP=0
while getopts ":d:t:c:r:m:M:s:p:wh" opt; do
case $opt in
d) RUNTIME="$OPTARG" ;;
t) THREADS_ARG="$OPTARG" ;;
c) CHUNK_PER_THREAD="$OPTARG" ;;
r) ROUNDS="$OPTARG" ;;
m) MIN="$OPTARG" ;;
M) MAX="$OPTARG" ;;
s) SEED="$OPTARG" ;;
p) PRESET="$OPTARG" ;;
w) INCLUDE_WRAP=1 ;;
h) usage; exit 0 ;;
:) echo "Missing argument for -$OPTARG" >&2; usage; exit 2 ;;
*) usage; exit 2 ;;
esac
done
shift $((OPTIND-1))
# Backward-compatible positional args
if [[ $# -ge 1 ]]; then RUNTIME="$1"; fi
if [[ $# -ge 2 ]]; then THREADS_ARG="$2"; fi
case "$PRESET" in
burst|BURST)
CHUNK_PER_THREAD=10000; ROUNDS=1 ;;
loop|LOOP)
CHUNK_PER_THREAD=100; ROUNDS=100 ;;
"" ) : ;;
*) echo "Unknown preset: $PRESET" >&2; exit 2 ;;
esac
# Params matching our standard runs (larson reads: runtime, min, max, chunks/thread, rounds, seed, threads)
# Show resolved parameters for reproducibility
echo "[CFG] runtime=${RUNTIME}s threads={${THREADS_ARG}} min=${MIN} max=${MAX} chunks/thread=${CHUNK_PER_THREAD} rounds=${ROUNDS} seed=${SEED}"
ROOT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
LIB_HAKMEM="$ROOT_DIR/libhakmem.so"
LARSON_BIN="$ROOT_DIR/mimalloc-bench/bench/larson/larson"
if [[ ! -x "$LARSON_BIN" ]]; then
echo "[ERR] Larson binary not found at: $LARSON_BIN" >&2
echo " Did you sync submodule/build bench?" >&2
exit 1
fi
if [[ ! -f "$LIB_HAKMEM" ]]; then
echo "[INFO] libhakmem.so not found; building..."
(cd "$ROOT_DIR" && make -j4 shared >/dev/null)
fi
abs_hakmem="$(readlink -f "$LIB_HAKMEM")"
detect_mimalloc() {
if [[ -n "${MIMALLOC_SO:-}" && -f "$MIMALLOC_SO" ]]; then
echo "$MIMALLOC_SO"
return 0
fi
# try common paths or ldconfig
for p in \
/usr/lib/x86_64-linux-gnu/libmimalloc.so.2 \
/lib/x86_64-linux-gnu/libmimalloc.so.2; do
[[ -f "$p" ]] && { echo "$p"; return 0; }
done
if command -v ldconfig >/dev/null 2>&1; then
so="$(ldconfig -p | awk '/libmimalloc.so/ {print $4; exit}')"
[[ -n "$so" && -f "$so" ]] && { echo "$so"; return 0; }
fi
return 1
}
mimalloc_so=""
if mimalloc_so=$(detect_mimalloc); then
:
else
mimalloc_so=""
fi
run_case() {
local label="$1"; shift
local preload="$1"; shift
local threads="$1"; shift
echo "\n== $label | ${threads}T | ${RUNTIME}s =="
if [[ -n "$preload" ]]; then
env LD_PRELOAD="$preload" "$LARSON_BIN" "$RUNTIME" "$MIN" "$MAX" "$CHUNK_PER_THREAD" "$ROUNDS" "$SEED" "$threads" 2>&1 | tail -n 3
else
"$LARSON_BIN" "$RUNTIME" "$MIN" "$MAX" "$CHUNK_PER_THREAD" "$ROUNDS" "$SEED" "$threads" 2>&1 | tail -n 3
fi
}
IFS=',' read -r -a THREADS <<< "$THREADS_ARG"
for t in "${THREADS[@]}"; do
# system malloc
run_case "system malloc" "" "$t"
# mimalloc (optional)
if [[ -n "$mimalloc_so" ]]; then
run_case "mimalloc" "$mimalloc_so" "$t"
else
echo "\n== mimalloc | ${t}T | ${RUNTIME}s =="
echo "[SKIP] libmimalloc not found"
fi
# hakmem default
run_case "hakmem (default)" "$abs_hakmem" "$t"
# hakmem wrap tiny (optional)
if [[ "$INCLUDE_WRAP" -eq 1 ]]; then
echo "\n== hakmem (HAKMEM_WRAP_TINY=1) | ${t}T | ${RUNTIME}s =="
HAKMEM_WRAP_TINY=1 LD_PRELOAD="$abs_hakmem" "$LARSON_BIN" "$RUNTIME" "$MIN" "$MAX" "$CHUNK_PER_THREAD" "$ROUNDS" "$SEED" "$t" 2>&1 | tail -n 3
fi
done
echo "\nDone."