Files
hakmem/scripts/larson.sh

328 lines
8.7 KiB
Bash
Raw Normal View History

#!/bin/bash
# larson.sh - Unified Larson benchmark runner
# Purpose: "1コマンドで正しい環境・同条件比較・結果保存"を保証
#
# Usage:
# scripts/larson.sh <command> [options] [duration] [threads]
#
# Commands:
# build - Build all targets (hakmem/mi/sys)
# hakmem - Run HAKMEM only
# mi - Run mimalloc only
# sys - Run system malloc only
# battle - Compare all 3 (hakmem vs mimalloc vs system)
# asan - Run with AddressSanitizer
# ubsan - Run with UBSan
# tsan - Run with ThreadSanitizer
# guard - Run with full safety checks (guard profile)
# debug - Run with debug ring (debug profile)
#
# Options:
# --profile <name> - Load profile from scripts/profiles/<name>.env
#
# Examples:
# scripts/larson.sh hakmem --profile tinyhot_tput 2 4
# scripts/larson.sh battle 2 4
# scripts/larson.sh guard 2 4
set -e
# ============================================================================
# Configuration
# ============================================================================
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
PROJECT_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
PROFILES_DIR="$SCRIPT_DIR/profiles"
RESULTS_DIR="$PROJECT_ROOT/benchmarks/results"
# Default Larson parameters (fixed for consistency)
DEFAULT_PARAMS="8 128 1024 1 12345"
# ============================================================================
# Helper Functions
# ============================================================================
usage() {
cat <<EOF
Usage: $0 <command> [options] [duration] [threads]
Commands:
build Build all targets (hakmem/mi/sys)
hakmem Run HAKMEM only
mi Run mimalloc only
sys Run system malloc only
battle Compare all 3 (hakmem vs mimalloc vs system)
asan Run with AddressSanitizer
ubsan Run with UBSan
tsan Run with ThreadSanitizer
guard Run with full safety checks
debug Run with debug ring
Options:
--profile <name> Load profile from scripts/profiles/<name>.env
Examples:
$0 hakmem --profile tinyhot_tput 2 4
$0 battle 2 4
$0 guard 2 4
EOF
exit 1
}
log() {
echo "[larson.sh] $*" >&2
}
error() {
echo "[larson.sh ERROR] $*" >&2
exit 1
}
# Load profile from scripts/profiles/*.env
load_profile() {
local profile_name="$1"
local profile_path="$PROFILES_DIR/${profile_name}.env"
if [[ ! -f "$profile_path" ]]; then
error "Profile not found: $profile_path"
fi
log "Loading profile: $profile_name"
# shellcheck disable=SC1090
source "$profile_path"
}
# Display current environment configuration
show_env() {
log "=========================================="
log "Environment Configuration:"
log "=========================================="
log "Tiny Fast Path: ${HAKMEM_TINY_FAST_PATH:-<not set>}"
# Program reads HAKMEM_TINY_USE_SUPERSLAB. Keep legacy var for backward compatibility.
log "SuperSlab: ${HAKMEM_TINY_USE_SUPERSLAB:-${HAKMEM_USE_SUPERSLAB:-<not set>}}"
log "SS Adopt: ${HAKMEM_TINY_SS_ADOPT:-<not set>}"
log "Box Refactor: ${HAKMEM_TINY_PHASE6_BOX_REFACTOR:-<not set>}"
log "Fast Cap 0: ${HAKMEM_TINY_FAST_CAP_0:-<not set>}"
log "Fast Cap 1: ${HAKMEM_TINY_FAST_CAP_1:-<not set>}"
log "Refill Count Hot: ${HAKMEM_TINY_REFILL_COUNT_HOT:-<not set>}"
log "SLL Only: ${HAKMEM_TINY_SLL_ONLY:-<not set>}"
log "TLS List Cap: ${HAKMEM_TINY_TLS_LIST_CAP:-<not set>}"
log "TLS Hot Mag Cap: ${HAKMEM_TINY_TLS_HOT_MAG_CAP:-<not set>}"
log "Trace Ring: ${HAKMEM_TINY_TRACE_RING:-<not set>}"
log "Safe Free: ${HAKMEM_TINY_SAFE_FREE:-<not set>}"
log "Remote Guard: ${HAKMEM_TINY_REMOTE_GUARD:-<not set>}"
log "Debug Counters: ${HAKMEM_DEBUG_COUNTERS:-<not set>}"
log "=========================================="
}
# Build target
build_target() {
local target="$1"
log "Building $target..."
cd "$PROJECT_ROOT"
make "$target" || error "Build failed: $target"
}
# Run Larson benchmark
run_larson() {
local binary="$1"
local duration="$2"
local threads="$3"
log "Running: $binary $duration $DEFAULT_PARAMS $threads"
cd "$PROJECT_ROOT"
"./$binary" "$duration" $DEFAULT_PARAMS "$threads"
}
# ============================================================================
# Command Handlers
# ============================================================================
cmd_build() {
log "Building all targets..."
build_target "larson_hakmem"
build_target "larson_system"
# Try to build mimalloc (may not exist)
if [[ -f "larson_mi.c" ]] || [[ -f "mimalloc-bench/bench/larson/larson.c" ]]; then
build_target "larson_mi" || log "Warning: mimalloc build failed (skipping)"
else
log "Warning: mimalloc source not found (skipping)"
fi
}
cmd_hakmem() {
local duration="$1"
local threads="$2"
build_target "larson_hakmem"
show_env
run_larson "larson_hakmem" "$duration" "$threads"
}
cmd_mi() {
local duration="$1"
local threads="$2"
build_target "larson_mi"
run_larson "larson_mi" "$duration" "$threads"
}
cmd_sys() {
local duration="$1"
local threads="$2"
build_target "larson_system"
run_larson "larson_system" "$duration" "$threads"
}
cmd_battle() {
local duration="$1"
local threads="$2"
local snapshot_dir="$RESULTS_DIR/snapshot_$(date +%Y%m%d_%H%M%S)"
log "==========================="
log "BATTLE MODE: 3-way comparison"
log "==========================="
mkdir -p "$snapshot_dir"
# Save environment
env | grep HAKMEM > "$snapshot_dir/env.txt" || true
# Build all
cmd_build
log "Running HAKMEM..."
run_larson "larson_hakmem" "$duration" "$threads" | tee "$snapshot_dir/hakmem.txt"
log "Running mimalloc..."
run_larson "larson_mi" "$duration" "$threads" | tee "$snapshot_dir/mimalloc.txt" || log "mimalloc skipped"
log "Running system malloc..."
run_larson "larson_system" "$duration" "$threads" | tee "$snapshot_dir/system.txt"
log "Results saved to: $snapshot_dir"
log "Summary:"
grep "Throughput" "$snapshot_dir"/*.txt || true
}
cmd_guard() {
local duration="$1"
local threads="$2"
load_profile "larson_guard"
cmd_hakmem "$duration" "$threads"
}
cmd_debug() {
local duration="$1"
local threads="$2"
load_profile "larson_debug"
cmd_hakmem "$duration" "$threads"
}
cmd_asan() {
local duration="$1"
local threads="$2"
build_target "larson_hakmem_asan"
show_env
run_larson "larson_hakmem_asan" "$duration" "$threads"
}
cmd_ubsan() {
local duration="$1"
local threads="$2"
build_target "larson_hakmem_ubsan"
show_env
run_larson "larson_hakmem_ubsan" "$duration" "$threads"
}
cmd_tsan() {
local duration="$1"
local threads="$2"
build_target "larson_hakmem_tsan"
show_env
run_larson "larson_hakmem_tsan" "$duration" "$threads"
}
# ============================================================================
# Main
# ============================================================================
main() {
if [[ $# -lt 1 ]]; then
usage
fi
local command="$1"
shift
# Parse options
local profile=""
while [[ $# -gt 0 ]]; do
case "$1" in
--profile)
profile="$2"
shift 2
;;
*)
break
;;
esac
done
# Load profile if specified
if [[ -n "$profile" ]]; then
load_profile "$profile"
fi
# Get duration and threads (optional, defaults to 2 and 4)
local duration="${1:-2}"
local threads="${2:-4}"
# Route to command handler
case "$command" in
build)
cmd_build
;;
hakmem)
cmd_hakmem "$duration" "$threads"
;;
mi|mimalloc)
cmd_mi "$duration" "$threads"
;;
sys|system)
cmd_sys "$duration" "$threads"
;;
battle)
cmd_battle "$duration" "$threads"
;;
guard)
cmd_guard "$duration" "$threads"
;;
debug)
cmd_debug "$duration" "$threads"
;;
asan)
cmd_asan "$duration" "$threads"
;;
ubsan)
cmd_ubsan "$duration" "$threads"
;;
tsan)
cmd_tsan "$duration" "$threads"
;;
*)
error "Unknown command: $command"
;;
esac
}
main "$@"