Repository navigation
Conversation
`specs/mobility-cost.md` section 2 said a position keyed cache could not work, because the full occupancy is among the term's inputs and moves every ply. The hit rate says otherwise. The clock says the spec reached the right conclusion by the wrong route. **This does not ship.** It is kept as the measurement. ## What repeats Over the bench, 29.21% of the term's 2,003,154 calls are on a position it has already scored in that search, and 18.43% land on a live entry of a table of 16,384. A transposition entry cuts only when the depth it was stored at suffices, so a position reached again deeper is searched again and evaluated again, and iterative deepening walks the same tree up to seven times over. The table removes the search below a repeat, not the evaluation at it. Section 5 of that spec said this finding falsifies section 2, and it does. ## What it saves, and what it costs Instructions fall 4,030,086,289 to 3,966,023,843, **-1.59%**, at the same 3,868,987 nodes. The term goes 13.11% of the run to 11.91%: the miss path falls 18.0%, which matches the hit rate, and the probe costs 40,689,060 back. The clock does not follow. At depth 9, fastest round of each side, six readings of the cache against the same base binary come to **-0.98% (+/- 0.44)** where five readings of a null come to +0.06%. Two standard errors put the difference between -1.85% and -0.10%, which does not reach zero. It executes 1.59% fewer instructions and takes about 1% longer. Callgrind offers no reason for it: last level misses are 295,846 against the bypassed tree's 295,843, flat to three digits. It models a first level and a last level, and neither an L2 nor a TLB, which is what a 256KB table probed at random pays. The saving is real and the payment is in a currency the profiler does not carry. ## The null test, which is the part worth keeping Every clock reading taken on this branch before that null was noise. A sweep of five table sizes read -0.2%, +0.5%, -5.3%, -6.1% and -1.7%, which looks like a memory effect and is not one. Two binaries of the same md5, compared by `scripts/speed.py` over 25 interleaved rounds at the default depth, read +1.1% between the medians and **-2.5% between the fastest rounds**. `docs/DEVELOPMENT.md` says the fastest pair is the one that survives a loaded runner, since nothing sharing the machine makes a run faster. That holds once a round is long enough to swamp what the clock does at a process start. The default depth is 0.34s a round and its null band is 2.5% wide. Depth 9 is 4.4s a round and closes it to +0.8% and -0.3% over five readings. **A one percent claim needs a round measured in seconds**, and the trailer below cannot say which was used: its grammar has no field for the depth. ## What is left One variant fits the evidence: an eight byte entry, a 32 bit fragment of the key beside the score, which halves the footprint at the same slot count. Callgrind cannot rule on it, having already reported no misses to remove, so it costs an hour of clock readings to decide. That is the owner's call rather than this branch's. Bench: 3868987 Speed: -0.6% (bench nps, 15 interleaved rounds vs 7e6ddd7, spread 33.5%) Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Contributor
Speed against
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Not for merge. The cache works, saves instructions and costs time. This is
the measurement, opened where it can be read rather than left on a branch.
specs/mobility-cost.mdsaid a position keyed cache could not work, becausemobility_countsreads the full occupancy and the occupancy changes everymove. The hit rate says otherwise. Over the bench, 29.21% of the term's
2,003,154 calls are on a position already scored in that search, and 18.43%
land on a live entry of a table of 16,384. A transposition entry cuts only
when the depth it was stored at suffices, so a position reached again deeper
is searched again and evaluated again, and iterative deepening walks the same
tree up to seven times over. The table removes the search below a repeat, not
the evaluation at it.
So it was built.
What it saves
At the same 3,868,987 nodes the run goes 4,030,086,289 instructions to
3,966,023,843, -1.59%. The term goes 13.11% of the run to 11.91%: its miss
path falls 18.0%, which matches the hit rate, and the probe costs 40,689,060
back.
What it costs
The clock does not follow. At depth 9, fastest round of each side against the
same base binary:
The difference is -0.98% (+/- 0.44), two standard errors putting it
between -1.85% and -0.10%, which does not reach zero. It executes 1.59% fewer
instructions and takes about 1% longer.
Callgrind offers no reason: last level misses are 295,846 against the bypassed
tree's 295,843, flat to three digits. It models a first level and a last
level, and neither an L2 nor a TLB, which is what a 256KB table probed at
random pays.
performance.mdalready records that 96% of this engine's L1misses are served by L2.
The null test, which is the part worth keeping
Every clock reading taken on this branch before the null was noise. A sweep of
five table sizes read -0.2%, +0.5%, -5.3%, -6.1% and -1.7%, which looks like a
memory effect and is five samples of the machine. Two binaries built from the
same commit, the same md5, compared over 25 interleaved rounds at the default
depth, read +1.1% between the medians and -2.5% between the fastest
rounds.
docs/DEVELOPMENT.mdsays the fastest pair is the one that survives a loadedrunner, since nothing sharing the machine makes a run faster. That holds once
a round is long enough to swamp what the clock does at a process start. The
default round is 0.34s. Depth 9 is 4.4s and closes the null band to +0.8% and
-0.3%, which is what let a 1% effect be read at all. The
Speed:trailer'sgrammar has no field for the depth, so a reading at 0.34s and one at 4.4s are
written down the same way.
What is left, both the owner's call
halves the footprint at the same slot count, which is the only variant the
evidence points at. Callgrind cannot rule on it, having already reported no
misses to remove, so it costs an hour of clock readings to decide.
it, against the 5%
specs/mobility.mdallows a leaf term, and the refitthat put it there is worth +76 elo. Either the figure means something, in
which case the term needs incremental maintenance, or it is a rule of thumb
and should say so.
One thing worth carrying into either: what repeats is the position, not the
mobility term. The same table, keyed the same way, would answer the whole
evaluation rather than one term of it, against the same memory traffic that
sank this one. That is a different arm.
Notes
7e6ddd7, where every number above was measured. master has movedseven commits since, two of them touching comments in
eval.rs.eval/term-modulessplitseval.rsinto a module per term. If that landsfirst, this branch does not apply as it stands.
the tactical suite's three in the release run, fmt clean, clippy quiet apart
from the standing
MAGICconst evaluation warning, and the bench reads3,868,987, which is the trailer.
🤖 Generated with Claude Code