Skip to content

feat(search): Add one ply continuation history to the quiet order from depth two - #416

Merged
aywrite merged 2 commits into
masterfrom
claude/arche-analysis-planning-mh1qzv
Nov 13, 2026
Merged

aywrite merged 2 commits into
masterfrom
claude/arche-analysis-planning-mh1qzv

Conversation

@aywrite

@aywrite aywrite commented Nov 13, 2026

Copy link
Copy Markdown
Owner

Adds a second history table to the quiet move order. A quiet's history is the butterfly entry plus an entry keyed by its piece and to square under the piece and to square of the move that reached the node. The table is taught by the same cutoff as the butterfly table and feeds the order alone.

A node reads and teaches the table only with two or more plies left. Below that it keys its quiets in the loop it had before. The same table read at every depth was played in October and read +6 ±8 over 4,000 games at about 0.95 of master's nodes a second. On the games suite 65% of quiet keying is at depth one, and the gate takes the table's cost on master's tree from 6.44% of instructions to 3.95% (1.39 points of each is the clear at each go, which a game pays once a move).

Result. Against 8e088cd at 10+0.1, sprt [0, 5] passed on its eleventh batch at LLR 3.01: +8 ±6 over 5,500 games, no game lost on time, at 0.970 to 0.989 of master's nodes a second. It is a stopped estimate and leans high. The interval clears zero, so no 30+0.3 match was played.

What is not shown. Over 268 game positions searched to depth 12 the tree is no smaller with the table (0.996 of master's nodes, 95% 0.932 to 1.064), so the threshold of two was chosen inside the noise. Depth three and a table read everywhere were not played against this one.

Checks. Bench 9,312,660 (from 11,916,992; promotions carries 51% of the fall). Tactical suite 231 (230), strategic suite 104,989 (104,395). Release and debug tests, clippy on both feature sets and fmt pass. The games were played on 4e77791, which differs from this commit in comments, one paragraph of docs/ARCHITECTURE.md and the two suite counts.

SearchConfig::continuation_history is the fifteenth switch, on by default and off in the reference.


Generated by Claude Code

…m depth two

A quiet's history is the butterfly entry plus an entry keyed by its piece
and to square under the piece and to square of the move that reached the
node. The second table is taught as the first is, by the same cutoff with
the same bonus, malus and bound, and is cleared at each go. A null move
leaves the node under it nothing to key by. The table feeds the order
alone.

A node reads and teaches the table only with two or more plies left, any
reduction and the check extension included, and a node is told the move
that reached it only where its parent has more than two. Under that a
node keys its quiets by the butterfly entry in the loop it had before.

The same table read at every depth was played in October and read +6 ±8
over 4,000 games at 0.946 to 0.961 of master's nodes a second. On the
games suite 65% of the quiets keyed are keyed at depth one and 21% at
depth two. Doing the table's work on master's exact tree costs 6.44% of
the suite's instructions read everywhere and 3.95% from depth two, and
1.39 points of each are the clear at each go, which the suite pays once a
position and a game once a move.

Over 268 positions from games, searched to depth 12, the tree is no
smaller with the table than without: 0.983 of master's nodes read
everywhere (95% 0.910 to 1.061) and 0.996 from depth two (0.932 to
1.064). The threshold was chosen on that and the cost together, and the
choice is inside the noise of both.

Against 8e088cd at 10+0.1 the sprt [0, 5] passed on its eleventh batch
at LLR 3.01: +8 ±6 over 5,500 games (pairs 123, 630, 1141, 704, 152),
with no game lost on time, at 0.970 to 0.989 of master's nodes a second
in every batch. The figure is a stopped estimate and leans high; the
batches read from -1 to +22. The games were played on 4e77791, which
differs from this commit in comments, a paragraph of the architecture
notes and the two suite counts below.

The bench falls 21.9% (11,916,992 to 9,312,660). Promotions carries 51%
of the fall (1,643,811 to 315,447), lucena 37% and perft 4 34%, while
the start position, the ruy lopez and the sharp middlegame grow. The
tactical suite finds 231 (230) and the strategic suite scores 104,989
(104,395). SearchConfig::continuation_history is the fifteenth switch,
on by default and off in the reference, where the bench is master's.

Bench: 9312660
Elo: +8 ±6 (sprt [0, 5] passed, 5500 games, 10+0.1, vs 8e088cd)
Co-Authored-By: Claude Fable 5.2 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EYmME6yiwe8qbHTU6UgM2z
RUSTSEC-2026-0486 marks the extended attribute functions of rustix
1.1.4 unsound, and cargo deny fails on it. The crate reaches the tree
only through tempfile under proptest, a dev dependency, so no shipped
binary changes.

Co-Authored-By: Claude Fable 5.2 <[email protected]>
Claude-Session: https://claude.ai/code/session_01EYmME6yiwe8qbHTU6UgM2z
@github-actions

Copy link
Copy Markdown
Contributor

Speed against 8e088cd1

Measured on INTEL(R) XEON(R) PLATINUM 8573C.
Both sides built with rustc 1.99.1 (58cf8f9c3 2026-10-13).

Both sides built and run on this runner in this job, the way
scripts/speed.sh measures a perf commit. Each round runs
both sides on a layout of its own, the same compiled code with
its code and data shuffled and moved, so the 95% interval carries
where the code landed as well as the run. The verdict holds the
interval against a 1% threshold. The default layout, the one a
release ships, is measured after as a diagnostic. The node
counts are the search's: they move when the search does, and a
speed change leaves them alone.

round     base nps  candidate nps  change
    1      4337097        4074153   -6.1%
    2      4405117        4137584   -6.1%
    3      4353732        4089421   -6.1%
    4      4281120        4108217   -4.0%
    5      4338639        4104397   -5.4%
    6      4330886        4165770   -3.8%
    7      4351388        4160076   -4.4%
    8      4403854        4171168   -5.3%
    9      4319328        4183646   -3.1%
   10      4316676        4165316   -3.5%
   11      4343316        4206573   -3.1%
   12      4378026        4196109   -4.2%
   13      4409423        4161535   -5.6%
   14      4423695        4207284   -4.9%
   15      4358536        4194483   -3.8%
   16      4464659        4206176   -5.8%
   17      4338016        4195005   -3.3%
   18      4375076        4262233   -2.6%
   19      4397555        4180343   -4.9%
   20      4367587        4124290   -5.6%
   21      4359698        4049859   -7.1%
   22      4360864        4129290   -5.3%
   23      4341923        4158904   -4.2%
   24      4304321        4162220   -3.3%
   25      4326989        4189006   -3.2%
   26      4438721        4173830   -6.0%
   27      4410992        4184635   -5.1%
   28      4372606        4216198   -3.6%
   29      4397728        4226340   -3.9%
   30      4435229        4189869   -5.5%
   31      4305231        4200278   -2.4%
   32      4358615        4177451   -4.2%
   33      4419393        4133995   -6.5%
   34      4349433        4201506   -3.4%
   35      4378872        4165942   -4.9%
   36      4346797        4148839   -4.6%
   37      4351546        4139454   -4.9%
   38      4481898        4214178   -6.0%
   39      4446733        4142609   -6.8%
   40      4361369        4192636   -3.9%

              nodes    time  median nps  faster half
base       11916992  2.73 s     4360281      4406470
candidate   9312660  2.23 s     4172499      4199889
change       -21.9%  -18.3%       -4.3%        -4.7%

paired change -4.6%, 95% interval -5.1% to -4.2%
diagnostic, on the default layout alone -4.2%, 95% interval -4.7% to -3.6%, 13 rounds

the node counts differ, so this is a search change as well as a speed
one. nps only says what a node costs. Time to depth is what the change is
worth at this depth, and whether the new tree is the right one is for
games to say.

Speed: -4.6% (bench nps, 95% interval -5.1% to -4.2%, 40 interleaved rounds over shuffled layouts vs 8e088cd1)

The instructions each side's bench executed, counted under
cachegrind. The count repeats to within a few hundred
instructions, so a small change here is a real one, but it
prices instructions only: cache misses, mispredicted branches
and where the code lands are the speed's to show.

instructions against 8e088cd1, one cachegrind run a side, bench

             instructions     nodes  per node
base       15,968,705,159  11916992    1340.0
candidate  13,159,580,915   9312660    1413.1
change            -17.59%   -21.85%    +5.45%

the trees differ, so the count moved with the search as well as the code; the per node column is the nearer reading

@aywrite
aywrite merged commit b0600cb into master Nov 13, 2026
21 checks passed
@aywrite
aywrite deleted the claude/arche-analysis-planning-mh1qzv branch November 13, 2026 05:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants