Drop 'capped' from per-policy figures (f4a, f4c×2, f6)

'capped' is not a routing policy — it's lmetric run on a separately
truncated trace (sessions capped to 8 turns via build_capped_trace.py).
Putting it alongside lmetric/load_only/sticky/unified in per-policy
comparison figures is misleading because the workload differs, not
the routing decision. Comparing apples to a different-trace orange
inflates/deflates apparent policy gaps for the wrong reasons.

Regenerated 4 figures with --exclude-policies capped on
analysis/characterization/render_window1_figures.py:
  - f4a_apc_loss.png                 (APC bars)
  - f4c_apc_vs_hotspot_tradeoff.png  (APC vs hotspot scatter)
  - f4c_per_worker_ttft.png          (per-worker TTFT panel)
  - f6_e2e_latency_bars.png          (TTFT/TPOT/E2E bars)

Added --exclude-policies CLI flag to the renderer so this is a
reversible choice, not a permanent script mutation. capped data remains
in b3_policy_comparison.json and can be brought back in workload-
sensitivity sections (where it actually belongs) by omitting the flag.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-05-27 10:57:43 +08:00
parent 74e0c2157a
commit 09ff1069c3
5 changed files with 10 additions and 0 deletions

View File

@@ -48,6 +48,8 @@ def fig_b3_apc_vs_hotspot(comp: dict, upper: dict, out: Path) -> None:
fig, ax = plt.subplots(figsize=(6, 4.5))
for r in comp["rows"]:
pol = r["policy"]
if pol not in POLICY_ORDER:
continue
ax.scatter(r["apc_ratio"] * 100, r["hotspot_index_ttft_p90"],
s=180, color=POLICY_COLOR.get(pol, "gray"), label=pol,
edgecolors="black", linewidths=0.5)
@@ -276,9 +278,17 @@ def main() -> None:
p = argparse.ArgumentParser()
p.add_argument("--results-dir", type=Path, required=True)
p.add_argument("--out-dir", type=Path, required=True)
p.add_argument("--exclude-policies", default="",
help="Comma-separated policies to drop from per-policy figures")
args = p.parse_args()
args.out_dir.mkdir(parents=True, exist_ok=True)
excluded = {s.strip() for s in args.exclude_policies.split(",") if s.strip()}
if excluded:
global POLICY_ORDER
POLICY_ORDER = [p for p in POLICY_ORDER if p not in excluded]
print(f"excluding policies: {sorted(excluded)} -> kept {POLICY_ORDER}")
comp = _load(args.results_dir, "b3_policy_comparison.json")
upper = _load(args.results_dir, "apc_upper_w600.json")
b2 = _load(args.results_dir, "b2_sweep_summary.json")

Binary file not shown.

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 35 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

After

Width:  |  Height:  |  Size: 37 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 52 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 58 KiB

After

Width:  |  Height:  |  Size: 54 KiB