The current result for start-position perft 10 is:
Code: Select all
Depth: 10
Nodes: 69,352,859,712,417
Time: 25.721 seconds
Logical rate: 2.696 trillion nodes/second
Threads: 32
TT: 48 GiB
Since this is hashed perft, the node rate is a logical rate: TT hits reuse completed subtree counts rather than physically visiting all 69 trillion leaves.
The part I found most interesting was that the TT was nowhere near saturating memory bandwidth. It used only about 21 GB/s, or 27.5% of the theoretical DDR5-4800 bandwidth. Random-access latency was the dominant problem.
To overlap more of that latency, I added batching when recursion reaches remaining depth 3. Each worker generates the depth-2 child positions into a queue, then processes that queue while prefetching TT buckets 20 positions ahead of consumption. The move generator, TT keys, lookup semantics and replacement policy remain unchanged.
That reduced the median from 30.059 to 25.721 seconds, a 14.43% improvement. IPC increased from 2.11 to 2.54 and measured L3 misses fell from 8.20 to 6.18 billion.
For another same-machine reference, MPerft 5.3 with its Clang PGO build completed the same calculation in 36.883 seconds.
Table allocation, zeroing and first-touch are outside the timer. Task generation, thread creation, calculation, joining and result reduction are included.
While expanding the validation suite I found and fixed two correctness defects in the earlier version. The current raw and hashed paths pass the 25-position suite with GCC and Clang, including sanitizer and collision-stress testing.
Source, build scripts, reproduction commands and the experiments that did not work:
https://github.com/vtlmks/mindchess
I am curious how this compares with other current CPU perft implementations, and particularly whether anyone has tried a similar batched-TT approach. There is probably still quite a lot hidden in the latency problem.