Skip to content

Commit dff941f

Browse files
committed
Add per-phase timing profile script across program sizes
1 parent 7b42e51 commit dff941f

1 file changed

Lines changed: 237 additions & 0 deletions

File tree

scripts/bench_timing_profile.sh

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
#!/bin/bash
2+
# Per-phase timing profile across program sizes.
3+
# Shows how each proving phase and sub-operation scales with program size.
4+
#
5+
# Usage: bench_timing_profile.sh [--no-build] [--programs "1M 2M 4M 8M"]
6+
#
7+
# Requires: instruments feature.
8+
# Timing is deterministic with instruments, so 1 run per size is enough.
9+
10+
set -euo pipefail
11+
12+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
13+
ROOT_DIR="$(cd "$SCRIPT_DIR/.." && pwd)"
14+
TMP_DIR="/tmp/bench_timing_profile"
15+
ELF_DIR="$ROOT_DIR/executor/program_artifacts/asm"
16+
17+
GREEN='\033[0;32m'
18+
BOLD='\033[1m'
19+
NC='\033[0m'
20+
21+
BUILD=true
22+
PROGRAMS="500k 1M 2M 4M"
23+
24+
while [[ $# -gt 0 ]]; do
25+
case $1 in
26+
--no-build) BUILD=false; shift ;;
27+
--programs) PROGRAMS="$2"; shift 2 ;;
28+
*) echo "Unknown arg: $1"; exit 1 ;;
29+
esac
30+
done
31+
32+
suffix_to_steps() {
33+
case $1 in
34+
160k) echo 160000 ;; 250k) echo 250000 ;; 372k) echo 372000 ;;
35+
500k) echo 500000 ;; 1M) echo 1000000 ;; 1200k) echo 1200000 ;;
36+
2M) echo 2000000 ;; 4M) echo 4000000 ;; 8M) echo 8000000 ;;
37+
16M) echo 16000000 ;; 32M) echo 32000000 ;; 64M) echo 64000000 ;; 128M) echo 128000000 ;;
38+
*) echo "Unknown: $1" >&2; exit 1 ;;
39+
esac
40+
}
41+
42+
rm -rf "$TMP_DIR" && mkdir -p "$TMP_DIR"
43+
44+
if $BUILD; then
45+
echo -e "${GREEN}Building CLI with instruments...${NC}"
46+
cargo build --release -p cli --features instruments \
47+
--manifest-path "$ROOT_DIR/Cargo.toml" 2>&1 | tail -1
48+
fi
49+
CLI="$ROOT_DIR/target/release/cli"
50+
51+
# Parse instruments stderr into key=value pairs.
52+
# Uses occurrence counting to disambiguate expand_pool_to_lde and commit (Merkle).
53+
parse_timing() {
54+
awk '
55+
BEGIN { lde_n = 0; merkle_n = 0 }
56+
function secs( s) {
57+
if (match($0, /[0-9]+\.[0-9]+s/)) {
58+
s = substr($0, RSTART, RLENGTH - 1)
59+
return s
60+
}
61+
return ""
62+
}
63+
/^ Execute / { v = secs(); if (v) print "execute=" v }
64+
/^ Trace build/ { v = secs(); if (v) print "trace_build=" v }
65+
/^ AIR construction/ { v = secs(); if (v) print "air=" v }
66+
/^ Pre-pass/ { v = secs(); if (v) print "prepass=" v }
67+
/^ Round 1 / { v = secs(); if (v) print "round1=" v }
68+
/Main trace commits/ { v = secs(); if (v) print "main_commits=" v }
69+
/Aux trace build/ { v = secs(); if (v) print "aux_build=" v }
70+
/Aux trace commit/ { v = secs(); if (v) print "aux_commit=" v }
71+
/Rounds 2/ { v = secs(); if (v) print "rounds24=" v }
72+
/expand_pool_to_lde/ && !/R1 expand/ {
73+
lde_n++; v = secs()
74+
if (v && lde_n == 1) print "main_lde=" v
75+
if (v && lde_n == 2) print "aux_lde=" v
76+
}
77+
/commit \(Merkle\)/ {
78+
merkle_n++; v = secs()
79+
if (v && merkle_n == 1) print "main_merkle=" v
80+
if (v && merkle_n == 2) print "aux_merkle=" v
81+
}
82+
/R1 expand_pool_to_lde/ { v = secs(); if (v) print "r1_lde=" v }
83+
/R2 evaluate/ { v = secs(); if (v) print "r2_evaluate=" v }
84+
/R2 decompose/ { v = secs(); if (v) print "r2_decompose=" v }
85+
/R2 commit_comp/ { v = secs(); if (v) print "r2_commit_comp=" v }
86+
/R3 OOD/ { v = secs(); if (v) print "r3_ood=" v }
87+
/R4 deep_comp/ { v = secs(); if (v) print "r4_deep_comp=" v }
88+
/R4 interpolate/ { v = secs(); if (v) print "r4_interp=" v }
89+
/R4 fri::commit/ { v = secs(); if (v) print "r4_fri_commit=" v }
90+
/R4 queries/ { v = secs(); if (v) print "r4_queries=" v }
91+
/^ Total FFT/ { v = secs(); if (v) print "total_fft=" v }
92+
/^ Total Merkle/ { v = secs(); if (v) print "total_merkle=" v }
93+
/^ TOTAL / { v = secs(); if (v) print "total=" v }
94+
' "$1"
95+
}
96+
97+
for size in $PROGRAMS; do
98+
ELF="$ELF_DIR/fib_iterative_${size}.elf"
99+
[ -f "$ELF" ] || { echo "Missing: $ELF"; continue; }
100+
steps=$(suffix_to_steps "$size")
101+
echo -e "${GREEN}Running fib_iterative_${size}...${NC}"
102+
103+
STDERR="$TMP_DIR/${size}_stderr.txt"
104+
"$CLI" prove "$ELF" -o "$TMP_DIR/proof.bin" 2>"$STDERR" >/dev/null
105+
rm -f "$TMP_DIR/proof.bin"
106+
107+
echo "steps=$steps" > "$TMP_DIR/${size}_data.txt"
108+
parse_timing "$STDERR" >> "$TMP_DIR/${size}_data.txt"
109+
done
110+
111+
# --- Display ---------------------------------------------------------------
112+
113+
get_val() {
114+
grep "^${2}=" "$1" 2>/dev/null | cut -d= -f2
115+
}
116+
117+
print_section() {
118+
local title=$1; shift
119+
120+
echo ""
121+
echo -e " ${BOLD}${title}${NC}"
122+
printf " %-30s" ""
123+
for size in $PROGRAMS; do printf " %9s" "$size"; done
124+
echo ""
125+
printf " %-30s" ""
126+
for size in $PROGRAMS; do printf " %9s" "─────────"; done
127+
echo ""
128+
129+
for spec in "$@"; do
130+
local label="${spec%%:*}"
131+
local key="${spec#*:}"
132+
printf " %-30s" "$label"
133+
for size in $PROGRAMS; do
134+
local DATA="$TMP_DIR/${size}_data.txt"
135+
local val
136+
val=$(get_val "$DATA" "$key")
137+
if [ -n "$val" ]; then
138+
printf " %8.2fs" "$val"
139+
else
140+
printf " %9s" "-"
141+
fi
142+
done
143+
echo ""
144+
done
145+
}
146+
147+
echo ""
148+
echo -e "${BOLD}=== TIMING PROFILE ACROSS SIZES ===${NC}"
149+
150+
TABLE_K="${TABLE_PARALLELISM:-default (cores/3)}"
151+
echo -e " TABLE_PARALLELISM=$TABLE_K"
152+
153+
print_section "Phase (wall time)" \
154+
"TOTAL:total" \
155+
"Execute:execute" \
156+
"Trace build:trace_build" \
157+
"AIR construction:air" \
158+
"Pre-pass:prepass" \
159+
"Round 1:round1" \
160+
"Rounds 2-4:rounds24"
161+
162+
print_section "Round 1 breakdown (CPU sum)" \
163+
"Main LDE:main_lde" \
164+
"Main Merkle:main_merkle" \
165+
"Aux build (wall):aux_build" \
166+
"Aux LDE:aux_lde" \
167+
"Aux Merkle:aux_merkle"
168+
169+
print_section "Rounds 2-4 sub-ops (CPU sum)" \
170+
"R1 LDE (reconstruct):r1_lde" \
171+
"R2 decompose+extend:r2_decompose" \
172+
"R2 evaluate:r2_evaluate" \
173+
"R2 commit comp poly:r2_commit_comp" \
174+
"R3 OOD evaluation:r3_ood" \
175+
"R4 deep comp evals:r4_deep_comp" \
176+
"R4 interpolate+evaluate:r4_interp" \
177+
"R4 FRI commit:r4_fri_commit" \
178+
"R4 queries & openings:r4_queries"
179+
180+
print_section "Cross-round totals (CPU sum)" \
181+
"Total FFT:total_fft" \
182+
"Total Merkle:total_merkle"
183+
184+
# --- Growth rate -----------------------------------------------------------
185+
186+
echo ""
187+
echo -e "${BOLD}=== GROWTH RATE (per 1M steps) ===${NC}"
188+
echo ""
189+
190+
for spec in \
191+
"TOTAL:total" \
192+
"Trace build:trace_build" \
193+
"Round 1:round1" \
194+
"Rounds 2-4:rounds24" \
195+
"Main LDE:main_lde" \
196+
"Aux LDE:aux_lde" \
197+
"R1 LDE (reconstruct):r1_lde" \
198+
"R2 decompose+extend:r2_decompose" \
199+
"R3 OOD evaluation:r3_ood" \
200+
"Total FFT:total_fft" \
201+
"Total Merkle:total_merkle"
202+
do
203+
label="${spec%%:*}"
204+
key="${spec#*:}"
205+
206+
PAIRS=""
207+
for size in $PROGRAMS; do
208+
DATA="$TMP_DIR/${size}_data.txt"
209+
[ -f "$DATA" ] || continue
210+
steps=$(get_val "$DATA" "steps")
211+
val=$(get_val "$DATA" "$key")
212+
[ -z "$val" ] && continue
213+
steps_m=$(awk "BEGIN {printf \"%.2f\", $steps / 1000000}")
214+
PAIRS="$PAIRS $steps_m $val"
215+
done
216+
217+
echo "$PAIRS" | awk -v label="$label" '{
218+
n = NF / 2
219+
if (n < 2) { printf " %-30s (insufficient data)\n", label; next }
220+
for (i = 0; i < n; i++) {
221+
x[i] = $(2*i+1); y[i] = $(2*i+2)
222+
}
223+
sx=0; sy=0; sxx=0; sxy=0
224+
for (i=0;i<n;i++) { sx+=x[i]; sy+=y[i]; sxx+=x[i]*x[i]; sxy+=x[i]*y[i] }
225+
denom = n*sxx - sx*sx
226+
if (denom == 0) { printf " %-30s (constant)\n", label; next }
227+
b = (n*sxy - sx*sy) / denom
228+
a = (sy - b*sx) / n
229+
ym = sy/n; ss_tot=0; ss_res=0
230+
for (i=0;i<n;i++) { p=a+b*x[i]; ss_res+=(y[i]-p)^2; ss_tot+=(y[i]-ym)^2 }
231+
r2 = (ss_tot>0) ? 1 - ss_res/ss_tot : 1
232+
printf " %-30s %+.2fs/M steps (base: %.2fs, R\xc2\xb2=%.3f)\n", label, b, a, r2
233+
}'
234+
done
235+
236+
echo ""
237+
echo "Raw data in $TMP_DIR/"

0 commit comments

Comments
 (0)