#!/usr/bin/env python3 """User-space instructions per thread name over an interval (perf stat --per-thread) — a load-independent cost measure: CPU % swings with other work on the machine and clock speed, retired instructions don't (smoke_run.sh step `instr:`). Usage: scripts/thread_instr.py PID SECONDS """ import re import subprocess import sys from collections import defaultdict def parse(text): """{thread name: instructions} from `perf stat --per-thread -x,` output.""" out = defaultdict(int) for line in text.splitlines(): parts = line.split(",") if len(parts) < 4 or "instructions" not in parts[3]: continue try: count = int(parts[1]) except ValueError: continue # out[re.sub(r"-\d+$", "", parts[0].strip())] += count return out def main(): pid, seconds = sys.argv[1], float(sys.argv[2]) res = subprocess.run(["perf", "stat", "--per-thread", "-x,", "-e", "instructions:u", "-p", pid, "--", "sleep", str(seconds)], capture_output=True, text=True) counts = parse(res.stderr) total = sum(counts.values()) print(f"instr: {total / seconds / 1e6:.0f} M/s total over {seconds:g}s") for name, n in sorted(counts.items(), key=lambda kv: -kv[1])[:8]: if n / seconds >= 1e6: print(f" {n / seconds / 1e6:7.0f} M/s {name}") if __name__ == "__main__": main()