#!/usr/bin/env python3 # -*- coding: utf-8 -*- """High vs RealTime 多轮 A/B,输出对比。结束后设为 --final 指定档。""" import json, os, subprocess, sys, time ROOT = os.path.normpath(os.path.join(os.path.dirname(__file__), "..")) LAB = os.path.join(ROOT, "lab", "skip_meter") def ecat_pid(): out = subprocess.check_output( ["powershell","-NoProfile","-Command","(Get-Process ecat_native).Id"], text=True).strip() return int(out.splitlines()[0]) def set_prio(level): p = ecat_pid() subprocess.check_output( ["powershell","-NoProfile","-Command", f"$p=Get-Process -Id {p}; $p.PriorityClass='{level}'; $p.PriorityClass"], text=True) return level def meter(tag, secs=12): r = subprocess.run([sys.executable, os.path.join(ROOT,"scripts","skip_rate_meter.py"), "--tag", tag, "--secs", str(secs)], capture_output=True, text=True, encoding="utf-8", errors="replace") files = sorted([f for f in os.listdir(LAB) if f.startswith(tag+"_") and f.endswith(".json")]) return json.load(open(os.path.join(LAB, files[-1]), encoding="utf-8")) def row(level, data, n): return { "round": n, "level": level, "late_per_s": data["late_per_s"], "skip_per_s": data["skip_per_s"], "send_stall_frac": data["send_stall_frac"], "rx_stall_frac": data["rx_stall_frac"], "achieved_hz": data["achieved_hz"], "n_late": data["n_late"], "send_p90": (data.get("window_cyc_us") or {}).get("send",{}).get("p90"), "work_p90": (data.get("window_cyc_us") or {}).get("work",{}).get("p90"), } def main(): final = "RealTime" if len(sys.argv) > 1: final = sys.argv[1] rows = [] # A-B-A-B seq = ["High","RealTime","High","RealTime"] for i, lv in enumerate(seq, 1): set_prio(lv) time.sleep(1.0) data = meter(f"ab_{lv}_{i}", 12) r = row(lv, data, i) rows.append(r) print(r) set_prio(final) print("FINAL", final, "pid", ecat_pid()) # summary means by = {} for r in rows: by.setdefault(r["level"], []).append(r) means = {} for lv, rs in by.items(): means[lv] = { "n": len(rs), "late_per_s_mean": round(sum(x["late_per_s"] for x in rs)/len(rs), 3), "skip_per_s_mean": round(sum(x["skip_per_s"] for x in rs)/len(rs), 3), "send_p90_mean": round(sum(x["send_p90"] or 0 for x in rs)/len(rs), 1), "work_p90_mean": round(sum(x["work_p90"] or 0 for x in rs)/len(rs), 1), } print("MEANS", json.dumps(means, ensure_ascii=False, indent=2)) path = os.path.join(LAB, f"summary_ab_prio_{int(time.time())}.json") json.dump({"rows": rows, "means": means, "final": final}, open(path,"w",encoding="utf-8"), ensure_ascii=False, indent=2) print("WROTE", path) if __name__ == "__main__": main()