3.7 KiB
§66d-4 — "ILS converged" means converged FOR THAT WEIGHT PROFILE, not a floor (amends §66d-3; Phase 29 SESSION-18)
§66d-3 gave the read-the-series rule: a repeat means stop, a fall means continue. That rule is right
about when to stop the current run and was over-applied to mean the function is at its floor.
SESSION-17 used it to record all four remaining giants as "at their measured permuter floor (ILS
converged)". func_8014D820 then fell from 16 to 10 under nothing but weight changes.
The measurement (func_8014D820, each pass warm-started from the previous pass's best waypoint):
| pass | profile | series | best |
|---|---|---|---|
| 1 | --klass REGALLOC |
14, then ×9 unchanged | 14 |
| 2 | --klass SCHEDULE |
12, then ×7 unchanged | 12 |
| 3 | --klass cse |
10, then ×9 unchanged | 10 |
Three profiles, three identical shapes: one drop in cycle 1, then dead flat. The flatness is real —
continuing that run is waste, exactly as §66d-3 says. But it is a statement about the mutation
distribution, not about the function: permuter_weights.classify biases decomp-permuter's pass
selection toward one class's levers (regalloc.md RC-, sched.md S-, the CSE address-fold levers), so a
converged run means this profile's neighbourhood is exhausted around this seed — and the seed has
just changed, because the pass rewrote it.
The rule, corrected:
- A flat series ⇒ stop this run. (§66d-3, unchanged.)
- Before calling a floor, re-run with a different
--klassfrom the new best waypoint. Only after all three profiles come back flat from the same seed have you measured a floor. - Cheap, unattended, ~0 tokens — so it is the first thing to try on any "converged" giant, ahead of reader time and far ahead of Fable5.
And check every pass's diff for operand-order regressions. A random search cannot tell that one of
its own edits made a local position worse while the total improved. The cse pass here swapped
if (p == ent) → if (ent == p), which cost idx 110 (beq $s2,$s1 vs the target's beq $s1,$s2);
reverting just that operand order, keeping every other gain, took 10 → 9 for one compile. Same for
x >= k ↔ k <= x. These are free points and they are invisible to the scorer's total.
⚠️ QUALIFY THIS: profile diversity is worth TRYING, but it is NOT reliable. Everything above is
measured on ONE function. The same session ran the identical experiment on func_80140958 — base 56,
prior profile regalloc, fresh --klass cse pass — and got best=56, zero improvement across all 8
cycles. So the honest rule is "before declaring a floor, spend one cheap unattended pass per unused
profile", not "each profile is worth ~2 points". Score so far: 3-for-3 on func_8014D820,
0-for-1 on func_80140958. The test is cheap enough (~0 tokens, unattended CPU) that it stays worth
running — but budget it as a lottery ticket, not as expected yield, and do not plan a session around it.
MEASURED: a repeated profile does NOT yield again. REGALLOC round-2, warm-started from the close=9 seed (a seed it had never seen — SCHEDULE, cse and a reader fix had rewritten it since), came back flat for all 10 cycles, 0 gain. So the lever is profile diversity, not seed novelty: each of the three profiles is worth about one drop, and re-spending one buys nothing. Budget accordingly — three passes per giant, then stop.
That also makes rule 2 above operational: a floor is measured when all three profiles come back flat
from the SAME seed. For func_8014D820 at close=9, REGALLOC is flat; SCHEDULE and cse from that seed
are the remaining evidence needed before calling 9 a floor.