Mindchess: raw, aggregate and hashed perft on Ryzen 9 9950X3D

Discussion of chess software programming and technical issues.

Moderator: Ras

vtlmks
Posts: 7
Joined: Fri Aug 07, 2026 4:59 am
Full name: Peter Fors

Mindchess: raw, aggregate and hashed perft on Ryzen 9 9950X3D

Post by vtlmks »

Mindchess: raw, aggregate and hashed perft on Ryzen 9 9950X3D

I think this will be the last Mindchess update for a while, so I wanted to collect the current results in one place.

Mindchess was never intended to become a chess engine. I don't have a particularly strong interest in chess itself; I started this because perft looked like a good optimization target. The original goal was simply to see how far I could push raw move generation, with Chessbit as the obvious program to compare against.

I reached that goal, but then stayed around long enough to optimize the other two variants as well: depth-2 aggregate counting and transposition-table perft.

Raw single-threaded perft

This is still what I consider the primary result. There is no transposition table or subtree reuse here; every legal leaf is actually enumerated.

The results are medians of five runs on my Ryzen 9 9950X3D:

Code: Select all

Position       Depth   Mindchess MNPS   Chessbit MNPS   Lead
--------------------------------------------------------------
Start             7          3680.26          2560.29   +43.744%
Kiwipete          6          4662.31          3455.52   +34.924%
Position 3        8          3015.91          2068.48   +45.803%
Position 4        6          3821.15          2956.15   +29.261%
Position 5        6          3882.35          2912.85   +33.284%
Position 6        6          5241.79          4173.73   +25.590%

Geometric mean                                          +35.241%
Rates are raw MNPS.

Raw multithreaded perft

The multithreaded version runs the same raw enumeration across workers, without a TT.

Start position, depth 9, 16 workers:

Code: Select all

Nodes:       2,439,530,234,167
Time:        43.758 s
Rate:        55,749.87 raw MNPS
Workers:     16
Split depth: 3
TT:          none
That corresponds to a 14.55x speedup and 90.93% scaling efficiency across 16 physical cores.

Depth-2 aggregate counting

After finishing the raw version I also experimented with avoiding work at depth 2 by proving groups of replies without constructing every child position.

For this comparison both Mindchess and Chessbit were built with ICX 2026.0.0, without PGO, and Chessbit's transposition table was disabled. The values are medians of five alternating runs:

Code: Select all

Position       Depth   Mindchess MNPS   Chessbit MNPS   Lead
--------------------------------------------------------------
Start             7          8641.51          7912.69    +9.211%
Kiwipete          6          7016.32          6896.50    +1.737%
Position 3        8          3276.70          3115.89    +5.161%
Position 4        6          4793.57          4474.56    +7.129%
Position 5        6          6441.44          5959.36    +8.089%
Position 6        6          9119.73          8835.76    +3.214%

Geometric mean                                           +5.724%
Again, these are MNPS, but unlike the raw numbers this version avoids some work at depth 2, so the rates should not be compared directly with raw MNPS.

Hashed / transposition-table perft

The final experiment was a multithreaded transposition-table version. This is a different benchmark again: transposed subtrees are reused, so the reported rate is logical nodes divided by elapsed time rather than physically enumerated leaves.

Start position depth 10, 69,352,859,712,417 logical nodes, 32 workers and an 8 GiB TT:

Code: Select all

Engine                 Build       Time       Logical MNPS
----------------------------------------------------------

Chessbit / ICX          non-PGO    12.020 s    5,769,788.66
Mindchess / Clang       non-PGO    10.204 s    6,796,816.11
Mindchess / Clang       PGO         9.579 s    7,240,438.70
The directly comparable non-PGO Mindchess result uses 15.11% less elapsed time than Chessbit and has 17.80% greater logical throughput.

Thomas deserves credit here. Chessbit provided the target that made this interesting in the first place, and he pointed me toward the depth-2 approach. Studying Chessbit also gave me useful ideas around recursive batching and cache-line bucket organization.

At this point I think I have done what I came for. I started out wanting to beat the raw implementation, achieved that, and then ended up staying around long enough to beat the aggregate and hashed versions as well.

There are certainly more things that could be optimized, but for now I feel done with the experiment.

I've cleaned up the repository so it now contains the three implementations separately, along with the build scripts, reproduction commands and transposition-table documentation:

https://github.com/vtlmks/mindchess

The two earlier threads contain the development history:

Raw perft:
https://talkchess.com/viewtopic.php?t=86611

Hashed perft:
https://talkchess.com/viewtopic.php?t=86623