143 lines
4.3 KiB
Bash
Executable File
143 lines
4.3 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
# M3: Generate flamegraphs + top hotspots for Manifest decode+profile (Ours vs Routinator).
|
|
#
|
|
# Outputs under:
|
|
# specs/develop/20260224/flamegraph/
|
|
# specs/develop/20260224/hotspots/
|
|
# specs/develop/20260224/perf/
|
|
#
|
|
# Notes:
|
|
# - On WSL2, /usr/bin/perf is often a wrapper that fails. This script uses a real perf binary
|
|
# from /usr/lib/linux-tools/*/perf (if present).
|
|
# - Ours profiling uses perf + flamegraph --perfdata to avoid rebuilding the whole crate graph
|
|
# with RocksDB.
|
|
|
|
ROOT_REPO="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
|
|
RPKI_DIR="$ROOT_REPO/rpki"
|
|
|
|
DATE_TAG="${DATE_TAG:-20260224}"
|
|
OUT_BASE="$ROOT_REPO/specs/develop/${DATE_TAG}"
|
|
OUT_FLAME="$OUT_BASE/flamegraph"
|
|
OUT_HOT="$OUT_BASE/hotspots"
|
|
OUT_PERF="$OUT_BASE/perf"
|
|
|
|
RUN_TAG="${RUN_TAG:-p2}"
|
|
|
|
OURS_BENCH_DIR="$RPKI_DIR/benchmark/ours_manifest_bench"
|
|
OURS_BIN="$OURS_BENCH_DIR/target/release/ours-manifest-bench"
|
|
|
|
ROUT_BENCH_DIR="${ROUT_BENCH_DIR:-/home/yuyr/dev/rust_playground/routinator/benchmark}"
|
|
ROUT_BIN="$ROUT_BENCH_DIR/target/release/routinator-manifest-benchmark"
|
|
ROUT_ISSUER="$ROUT_BENCH_DIR/fixtures/ta.cer"
|
|
|
|
PROFILE_HZ="${PROFILE_HZ:-99}"
|
|
|
|
mkdir -p "$OUT_FLAME" "$OUT_HOT" "$OUT_PERF"
|
|
|
|
PERF_WRAPPER_OUT="$(perf --version 2>&1 || true)"
|
|
PERF_REAL=""
|
|
if echo "${PERF_WRAPPER_OUT}" | grep -q "WARNING: perf not found for kernel"; then
|
|
PERF_REAL="$(ls -1 /usr/lib/linux-tools/*/perf 2>/dev/null | head -n 1 || true)"
|
|
else
|
|
PERF_REAL="$(command -v perf || true)"
|
|
fi
|
|
|
|
if [[ -z "${PERF_REAL}" ]]; then
|
|
echo "ERROR: usable perf binary not found (wrapper detected and no /usr/lib/linux-tools/*/perf)." >&2
|
|
exit 2
|
|
fi
|
|
|
|
SHIM_DIR="$RPKI_DIR/target/bench/tools"
|
|
mkdir -p "$SHIM_DIR"
|
|
cat > "$SHIM_DIR/perf" <<EOF
|
|
#!/usr/bin/env bash
|
|
exec "${PERF_REAL}" "\$@"
|
|
EOF
|
|
chmod +x "$SHIM_DIR/perf"
|
|
export PATH="$SHIM_DIR:$PATH"
|
|
|
|
echo "Using perf: $PERF_REAL"
|
|
|
|
echo "[1/3] Build ours benchmark with frame pointers..."
|
|
(cd "$OURS_BENCH_DIR" && RUSTFLAGS="-C force-frame-pointers=yes" cargo build --release -q)
|
|
|
|
echo "[2/3] Build routinator benchmark (release)..."
|
|
(cd "$ROUT_BENCH_DIR" && cargo build --release -q)
|
|
|
|
taskset_prefix=""
|
|
if command -v taskset >/dev/null 2>&1; then
|
|
taskset_prefix="taskset -c 0"
|
|
fi
|
|
|
|
profile_ours() {
|
|
local sample="$1"
|
|
local iters="$2"
|
|
local warm="$3"
|
|
local fixture="$RPKI_DIR/tests/benchmark/selected_der/${sample}.mft"
|
|
if [[ ! -f "$fixture" ]]; then
|
|
echo "ERROR: ours fixture not found: $fixture" >&2
|
|
exit 1
|
|
fi
|
|
|
|
local perfdata="$OUT_PERF/ours_${sample}_${RUN_TAG}.perf.data"
|
|
local svg="$OUT_FLAME/ours_${sample}_${RUN_TAG}.svg"
|
|
local tsv="$OUT_HOT/ours_${sample}_${RUN_TAG}.tsv"
|
|
|
|
echo "== ours $sample (iters=$iters warmup=$warm hz=$PROFILE_HZ)"
|
|
$taskset_prefix perf record -o "$perfdata" -F "$PROFILE_HZ" -g -- \
|
|
"$OURS_BIN" --manifest "$fixture" --iterations "$iters" --warmup-iterations "$warm" --repeats 1 >/dev/null
|
|
|
|
flamegraph --perfdata "$perfdata" --output "$svg" --title "ours ${sample} ManifestObject::decode_der" --deterministic >/dev/null
|
|
|
|
perf report -i "$perfdata" --stdio --no-children --sort symbol --percent-limit 0.5 \
|
|
| awk '/^[[:space:]]*[0-9.]+%/ {pct=$1; sub(/%/,"",pct); $1=""; sub(/^[[:space:]]+/,""); print pct "\t" $0}' \
|
|
> "$tsv"
|
|
}
|
|
|
|
profile_routinator() {
|
|
local sample="$1"
|
|
local iters="$2"
|
|
local warm="$3"
|
|
local fixture="$ROUT_BENCH_DIR/fixtures/selected_der/${sample}.mft"
|
|
if [[ ! -f "$fixture" ]]; then
|
|
echo "ERROR: routinator fixture not found: $fixture" >&2
|
|
exit 1
|
|
fi
|
|
|
|
local svg="$OUT_FLAME/routinator_${sample}_${RUN_TAG}.svg"
|
|
local tsv="$OUT_HOT/routinator_${sample}_${RUN_TAG}.tsv"
|
|
|
|
echo "== routinator $sample (iters=$iters warmup=$warm hz=$PROFILE_HZ)"
|
|
$taskset_prefix "$ROUT_BIN" \
|
|
--target decode_only \
|
|
--manifest "$fixture" \
|
|
--issuer "$ROUT_ISSUER" \
|
|
--iterations "$iters" \
|
|
--repeats 1 \
|
|
--warmup-iterations "$warm" \
|
|
--strict false \
|
|
--profile-hz "$PROFILE_HZ" \
|
|
--flamegraph "$svg" \
|
|
--hotspots "$tsv" \
|
|
>/dev/null
|
|
}
|
|
|
|
echo "[3/3] Profile samples..."
|
|
|
|
# Choose iterations so each capture runs ~10-20s serially.
|
|
profile_ours small-01 200000 0
|
|
profile_routinator small-01 200000 0
|
|
|
|
profile_ours large-02 50000 0
|
|
profile_routinator large-02 50000 0
|
|
|
|
profile_ours xlarge-02 5000 0
|
|
profile_routinator xlarge-02 5000 0
|
|
|
|
echo "Done."
|
|
echo "- Flamegraphs: $OUT_FLAME/"
|
|
echo "- Hotspots: $OUT_HOT/"
|
|
echo "- Perf data: $OUT_PERF/"
|