added standalone run scripts for all tests and experiments
This commit is contained in:
@@ -2,64 +2,167 @@
|
||||
set -euo pipefail
|
||||
LC_ALL=C
|
||||
|
||||
DIR=$(cd "$(dirname "$0")" && pwd)
|
||||
cd "$DIR"
|
||||
ROOT_DIR=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
RUN_ID=$(date +"%Y%m%d_%H%M%S")
|
||||
OUT_DIR="$ROOT_DIR/runs/$RUN_ID"
|
||||
mkdir -p "$OUT_DIR"
|
||||
|
||||
gcc -O2 -pthread -o pi_digits_benchmark pi_digits_benchmark.c
|
||||
LOG_FILE="$OUT_DIR/activity.log"
|
||||
|
||||
echo "Compiled pi_digits_benchmark"
|
||||
log() {
|
||||
echo "[$(date -Iseconds)] $*" | tee -a "$LOG_FILE"
|
||||
}
|
||||
|
||||
count_processes() {
|
||||
ls -d /proc/[0-9]* 2>/dev/null | wc -l
|
||||
}
|
||||
|
||||
count_threads_total() {
|
||||
awk '/^Threads:/ {sum+=$2} END {print sum+0}' /proc/[0-9]*/status 2>/dev/null || echo 0
|
||||
}
|
||||
|
||||
get_mem_kb() {
|
||||
awk '/^MemTotal:/ {t=$2} /^MemAvailable:/ {a=$2} END {print t" "a}' /proc/meminfo
|
||||
}
|
||||
|
||||
sample_process_csv() {
|
||||
local pid="$1"
|
||||
local csv="$2"
|
||||
local start_uptime="$3"
|
||||
local max_seconds="$4"
|
||||
|
||||
local have_pidstat=0
|
||||
if command -v pidstat >/dev/null 2>&1; then
|
||||
have_pidstat=1
|
||||
else
|
||||
log "pidstat not found; install sysstat for accurate CPU sampling"
|
||||
fi
|
||||
|
||||
local prev_cpu_total=0
|
||||
local prev_cpu_idle=0
|
||||
if [ -r /proc/stat ]; then
|
||||
read -r _ c_user c_nice c_system c_idle c_iowait c_irq c_softirq c_steal _ _ < /proc/stat
|
||||
prev_cpu_total=$((c_user + c_nice + c_system + c_idle + c_iowait + c_irq + c_softirq + c_steal))
|
||||
prev_cpu_idle=$((c_idle + c_iowait))
|
||||
fi
|
||||
|
||||
while kill -0 "$pid" 2>/dev/null; do
|
||||
local now_uptime elapsed_s
|
||||
now_uptime=$(awk '{print $1}' /proc/uptime)
|
||||
elapsed_s=$(awk -v s="$start_uptime" -v n="$now_uptime" 'BEGIN{printf "%.3f", (n-s)}')
|
||||
|
||||
if [ "$max_seconds" -gt 0 ]; then
|
||||
if awk -v e="$elapsed_s" -v m="$max_seconds" 'BEGIN{exit (e>m)?0:1}'; then
|
||||
log "Timeout reached (${max_seconds}s), stopping PID=$pid"
|
||||
kill -TERM "-$pid" 2>/dev/null || true
|
||||
sleep 2
|
||||
kill -KILL "-$pid" 2>/dev/null || true
|
||||
break
|
||||
fi
|
||||
fi
|
||||
|
||||
local proc_count thread_total
|
||||
proc_count=$(count_processes || echo 0)
|
||||
thread_total=$(count_threads_total || echo 0)
|
||||
|
||||
local load1 load5 load15
|
||||
read -r load1 load5 load15 _ < /proc/loadavg
|
||||
|
||||
local mem_total mem_avail mem_used
|
||||
read -r mem_total mem_avail < <(get_mem_kb || echo "0 0")
|
||||
mem_used=$((mem_total - mem_avail))
|
||||
|
||||
local cpu rss vsz nlwp
|
||||
rss=$(awk '/^VmRSS:/ {print $2}' "/proc/$pid/status" 2>/dev/null || echo 0)
|
||||
vsz=$(awk '/^VmSize:/ {print $2}' "/proc/$pid/status" 2>/dev/null || echo 0)
|
||||
nlwp=$(awk '/^Threads:/ {print $2}' "/proc/$pid/status" 2>/dev/null || echo 0)
|
||||
if [ "$have_pidstat" -eq 1 ]; then
|
||||
cpu=$(pidstat -p "$pid" 1 1 2>/dev/null | awk -v p="$pid" '$1 ~ /^[0-9]/ && $3==p {print $8; exit}')
|
||||
cpu=${cpu:-0.00}
|
||||
else
|
||||
cpu=0.00
|
||||
fi
|
||||
local stk=0 heap=0
|
||||
|
||||
local sys_cpu_pct=0.00
|
||||
if [ -r /proc/stat ]; then
|
||||
read -r _ c_user c_nice c_system c_idle c_iowait c_irq c_softirq c_steal _ _ < /proc/stat
|
||||
local cpu_total=$((c_user + c_nice + c_system + c_idle + c_iowait + c_irq + c_softirq + c_steal))
|
||||
local cpu_idle=$((c_idle + c_iowait))
|
||||
local dt_total=$((cpu_total - prev_cpu_total))
|
||||
local dt_idle=$((cpu_idle - prev_cpu_idle))
|
||||
sys_cpu_pct=$(awk -v t="$dt_total" -v i="$dt_idle" 'BEGIN{ if (t<=0) printf "0.00"; else printf "%.2f", (100.0*(t-i))/t }')
|
||||
prev_cpu_total=$cpu_total
|
||||
prev_cpu_idle=$cpu_idle
|
||||
fi
|
||||
|
||||
printf "%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s\n" \
|
||||
"$(date -Iseconds)" "$elapsed_s" "$load1" "$load5" "$load15" \
|
||||
"$mem_total" "$mem_avail" "$mem_used" "$proc_count" "$thread_total" \
|
||||
"$pid" "$cpu" "$sys_cpu_pct" "${rss:-0}" "${vsz:-0}" "${stk:-0}" "${heap:-0}" "${nlwp:-0}" \
|
||||
>> "$csv"
|
||||
|
||||
sleep 0.2
|
||||
done
|
||||
}
|
||||
|
||||
run_with_sampling() {
|
||||
local name="$1"
|
||||
local cmd="$2"
|
||||
local csv="$3"
|
||||
local max_seconds="$4"
|
||||
|
||||
log "Starting $name: $cmd"
|
||||
|
||||
echo "timestamp,elapsed_s,load1,load5,load15,mem_total_kb,mem_available_kb,mem_used_kb,proc_count,thread_count_total,pid,cpu_pct,sys_cpu_pct,rss_kb,vsz_kb,stack_kb,heap_kb,proc_threads" > "$csv"
|
||||
|
||||
local start_uptime pid
|
||||
start_uptime=$(awk '{print $1}' /proc/uptime)
|
||||
|
||||
if command -v setsid >/dev/null 2>&1; then
|
||||
setsid bash -c "$cmd" &
|
||||
pid=$!
|
||||
else
|
||||
bash -c "$cmd" &
|
||||
pid=$!
|
||||
fi
|
||||
|
||||
sample_process_csv "$pid" "$csv" "$start_uptime" "$max_seconds"
|
||||
|
||||
set +e
|
||||
wait "$pid"
|
||||
local exit_code=$?
|
||||
set -e
|
||||
|
||||
log "Finished $name (exit_code=$exit_code)"
|
||||
}
|
||||
|
||||
log "Compiling pi_digits_benchmark"
|
||||
gcc -O2 -pthread -o "$ROOT_DIR/pi_digits_benchmark" "$ROOT_DIR/pi_digits_benchmark.c"
|
||||
|
||||
THREAD_COUNT=${THREAD_COUNT:-4}
|
||||
PROCESS_COUNT=${PROCESS_COUNT:-4}
|
||||
PI_DIGITS=${PI_DIGITS:-2000}
|
||||
CHUNK_SIZE=${CHUNK_SIZE:-500}
|
||||
|
||||
RUNS_DIR="$DIR/runs"
|
||||
mkdir -p "$RUNS_DIR"
|
||||
RUN_ID=$(date +"%Y%m%d_%H%M%S")
|
||||
PI_BENCH_OUT_BASE="$OUT_DIR/pi_digits_benchmark"
|
||||
|
||||
RESULTS_CSV="$DIR/results.csv"
|
||||
if [ ! -f "$RESULTS_CSV" ]; then
|
||||
echo "run_id,timestamp,host,kernel,mode,worker_count,pi_digits,chunk_size,exit_code,wall_s,cpu_user_s,cpu_sys_s,cpu_pct,max_rss_kb,max_vsz_kb,agg_rss_kb,agg_vsz_kb,agg_pss_kb,mem_snapshot_s,final_output_bytes" > "$RESULTS_CSV"
|
||||
fi
|
||||
PI_THREAD_STDOUT="$OUT_DIR/pi_digits_thread_stdout.log"
|
||||
PI_THREAD_STDERR="$OUT_DIR/pi_digits_thread_stderr.log"
|
||||
PI_PROC_STDOUT="$OUT_DIR/pi_digits_process_stdout.log"
|
||||
PI_PROC_STDERR="$OUT_DIR/pi_digits_process_stderr.log"
|
||||
|
||||
run_mode() {
|
||||
local mode="$1"
|
||||
local out_dir="$RUNS_DIR/${RUN_ID}_${mode}"
|
||||
local stdout_log="$out_dir/stdout.log"
|
||||
local stderr_log="$out_dir/stderr.log"
|
||||
run_with_sampling \
|
||||
"pi_digits_benchmark_thread" \
|
||||
"cd '$ROOT_DIR' && THREAD_COUNT='$THREAD_COUNT' PROCESS_COUNT='$PROCESS_COUNT' PI_DIGITS='$PI_DIGITS' CHUNK_SIZE='$CHUNK_SIZE' ./pi_digits_benchmark --mode thread --out-dir '$PI_BENCH_OUT_BASE/thread' >'$PI_THREAD_STDOUT' 2>'$PI_THREAD_STDERR'" \
|
||||
"$OUT_DIR/pi_digits_thread.csv" \
|
||||
0
|
||||
|
||||
mkdir -p "$out_dir"
|
||||
run_with_sampling \
|
||||
"pi_digits_benchmark_process" \
|
||||
"cd '$ROOT_DIR' && THREAD_COUNT='$THREAD_COUNT' PROCESS_COUNT='$PROCESS_COUNT' PI_DIGITS='$PI_DIGITS' CHUNK_SIZE='$CHUNK_SIZE' ./pi_digits_benchmark --mode process --out-dir '$PI_BENCH_OUT_BASE/process' >'$PI_PROC_STDOUT' 2>'$PI_PROC_STDERR'" \
|
||||
"$OUT_DIR/pi_digits_process.csv" \
|
||||
0
|
||||
|
||||
echo "Running mode=$mode out_dir=$out_dir"
|
||||
THREAD_COUNT="$THREAD_COUNT" PROCESS_COUNT="$PROCESS_COUNT" PI_DIGITS="$PI_DIGITS" CHUNK_SIZE="$CHUNK_SIZE" \
|
||||
./pi_digits_benchmark --mode "$mode" --out-dir "$out_dir" >"$stdout_log" 2>"$stderr_log"
|
||||
|
||||
if [ -f "$out_dir/results.csv" ]; then
|
||||
tail -n 1 "$out_dir/results.csv" >> "$RESULTS_CSV"
|
||||
fi
|
||||
|
||||
echo " stdout: $stdout_log"
|
||||
echo " stderr: $stderr_log"
|
||||
echo " results: $out_dir/results.csv"
|
||||
echo " workers: $out_dir/workers.csv"
|
||||
echo " pi output: $out_dir/pi_digits.txt"
|
||||
}
|
||||
|
||||
MODE=${1:-both}
|
||||
case "$MODE" in
|
||||
thread)
|
||||
run_mode thread
|
||||
;;
|
||||
process)
|
||||
run_mode process
|
||||
;;
|
||||
both)
|
||||
run_mode thread
|
||||
run_mode process
|
||||
;;
|
||||
*)
|
||||
echo "Usage: $0 [thread|process|both]"
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
log "Experiment finished"
|
||||
log "Run directory: $OUT_DIR"
|
||||
|
||||
Reference in New Issue
Block a user