Files
VoxelForge/Standalone/Research/WorldAssemblerM3/Linux137/AnalyzeL137Profile.py
T
Fr0zkaandClaude Opus 5.5 05e78331fe core: A/A noise floor (±1%) and small hot-path trims for the cave planner (L137, output = v236)
Identical builds differ <=0.6% median; residual near-ready vs assembler/world is real: Surface World +2.9..+3.6%,
Vertical Shafts +4.0..+4.3%, Tunnel Network -3.6/+6.8%. Profile points at column-cache reads and the sweep lookup.
Removed an unused sample field and per-lookup shared_ptr refcounting. 16/16 seeds, fast tier, Clang/GCC green.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_016dhxM43dnWvUu2B5Ph1iG1
2026-11-01 03:22:55 +01:00

121 lines
4.9 KiB
Python

#!/usr/bin/env python3
"""Symbolize L137 L77 samples and compare inclusive worker functions."""
from __future__ import annotations
import csv
import json
import re
import subprocess
from collections import Counter
from pathlib import Path
ROOT = Path(__file__).resolve().parents[4]
OUT = ROOT / "Saved/Linux/l137/profile"
BINARIES = {
"assembler-world": ROOT / "Saved/Linux/l137/profile-bin/VoxelForgeCoreHeadless-l137-profile-base",
"head": ROOT / "Saved/Linux/l137/profile-bin/VoxelForgeCoreHeadless-l137-profile-head",
}
SAMPLE_RE = re.compile(
r"^\[L77Sample\] pc=(0x\w+) lod=(\d+) stage=(\S+) route=(\S+) "
r"phase=(\S+) halo=(\d+) weight=(\d+)$", re.M)
def samples(version: str) -> tuple[list[dict], set[str]]:
rows, pcs = [], set()
for replicate in (1, 2, 3):
path = OUT / f"sw-{version}-r{replicate}.log"
for pc, lod, stage, route, phase, halo, weight in SAMPLE_RE.findall(
path.read_text(encoding="utf-8", errors="replace")):
lod_value = int(lod)
if not 0 <= lod_value <= 8:
continue
pcs.add(pc)
rows.append({"version": version, "replicate": replicate,
"pc": pc, "lod": lod_value, "stage": stage,
"route": route, "phase": phase, "halo": int(halo),
"weight": int(weight)})
return rows, pcs
def symbolize(version: str, pcs: set[str]) -> dict[str, str]:
command = ["llvm-symbolizer-19", "--demangle", "--inlines", "--output-style=JSON",
f"--obj={BINARIES[version]}"]
result = subprocess.run(command, input="\n".join(sorted(pcs)) + "\n",
capture_output=True, text=True, check=True)
decoder = json.JSONDecoder()
offset, output = 0, {}
while offset < len(result.stdout):
while offset < len(result.stdout) and result.stdout[offset].isspace():
offset += 1
if offset == len(result.stdout):
break
item, offset = decoder.raw_decode(result.stdout, offset)
frames = item.get("Symbol", [])
output[item["Address"]] = (
frames[0].get("FunctionName", "?") if frames else "?")
if output.keys() != pcs:
raise RuntimeError(f"{version}: symbolizer resolved {len(output)}/{len(pcs)} PCs")
return output
def main() -> int:
totals: dict[str, Counter] = {}
lod_totals: dict[str, Counter] = {}
detail_rows = []
for version in BINARIES:
rows, pcs = samples(version)
symbols = symbolize(version, pcs)
totals[version] = Counter()
lod_totals[version] = Counter()
for row in rows:
function = symbols[row["pc"]]
weight = row["weight"]
totals[version][function] += weight
lod_totals[version][row["lod"]] += weight
detail_rows.append({**row, "function": function})
total_by_version = {key: sum(counter.values()) for key, counter in totals.items()}
functions = set(totals["assembler-world"]) | set(totals["head"])
result = []
for function in functions:
base_ticks = totals["assembler-world"][function]
head_ticks = totals["head"][function]
base_pct = 100.0 * base_ticks / total_by_version["assembler-world"]
head_pct = 100.0 * head_ticks / total_by_version["head"]
result.append({
"function": function,
"assembler_world_ticks": base_ticks,
"assembler_world_share_pct": round(base_pct, 3),
"head_ticks": head_ticks,
"head_share_pct": round(head_pct, 3),
"share_delta_pp": round(head_pct - base_pct, 3),
})
result.sort(key=lambda row: abs(row["share_delta_pp"]), reverse=True)
with (OUT / "function-diff.csv").open("w", encoding="utf-8", newline="") as stream:
writer = csv.DictWriter(stream, fieldnames=list(result[0]))
writer.writeheader()
writer.writerows(result)
with (OUT / "symbolized-samples.csv").open(
"w", encoding="utf-8", newline="") as stream:
writer = csv.DictWriter(stream, fieldnames=list(detail_rows[0]))
writer.writeheader()
writer.writerows(detail_rows)
summary = {
"scope": "worker samples LOD0-8, all LODs included; lod=255 main-thread samples excluded",
"runs_per_version": 3,
"weighted_ticks": total_by_version,
"lod_weighted_ticks": {version: dict(sorted(values.items()))
for version, values in lod_totals.items()},
"function_diff": result,
}
(OUT / "function-diff.json").write_text(
json.dumps(summary, indent=2) + "\n", encoding="utf-8")
print("[L137ProfileDiff] " + json.dumps({
"scope": summary["scope"], "weighted_ticks": total_by_version,
"lod_weighted_ticks": summary["lod_weighted_ticks"],
"largest_share_deltas": result[:20]}, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())