I wrote a Chess960 movegenerator tool called LastEmperor some time ago. It has exactly the same movegenerator as in Sapeli. But score and other game playing stuff is cleaned out. It uses hash+bulk counting: I don't even incrementally update hash.mvanthoor wrote: ↑Tue Apr 07, 2020 1:05 pmCrafty runs Perft 7 from the starting position in 55 seconds on my system. That's about half the time of Rustic. I assume Crafty has a more advanced move generator. It probably checks for being in check, double check, pinned pieces, etc... i.e., generating less illegal moves, and thus saving a lot of time making and then unmaking illegal moves.
Rustic doesn't do this (yet), so when the king is in check or if pieces are pinned, it still generates huge amounts of illegal moves. If you're in double check, all moves except king moves are illegal. These are optimizations that are going to be done later. First finish the search and uci protocol (and making my Rust code more idiomatic )
This evening I'll post some outputs.
@Terje:
In my case, Rustic is now slower when using the GNU toolchain for Rust. In the beginning when I started perft testing, it didn't matter, but for some reason (there were several Rust updates for example, since I neglected updating for some time), a GNU-toolchain compile now takes 120 seconds for Perft 7 from the starting position, while an MSVC compile takes 114 seconds. As the rustc compiler is the same in both toolchains, it seems MSVC's "link.exe" is more efficient in doing link-time optimization than GNU's ld.exe, on Windows.
Next to that, I probably also lost some speed, due to:
- Fixing two zobrist hash bugs (so there are now more zobrist XOR commands)
- Splitting a very long and ugly make_move() into several functions. To make this possible, it was necessary to take out a reference that went directly into the Board-struct. (Rust doesn't allow you to take mutliple mutable references into the same entity at the same time.) Therefore I now have to decide each time (in the new function) if I need to use the black or white pieces bitboard when setting or removing a piece. That check that's now done a huge amount of times as compared to just checking once and taking the pointer, will probably be responsible for some of the speed loss.
In this case, it's a speed vs. code readability/maintainability issue. The above two points lost about a second (113.2 vs 114.3) in perft 7 from the starting position, which at this point, is a speed loss of about 1%. I can live with that, getting much clearner code and better maintainability in return. In the end, the optimizations to the move generator itself will have a much bigger impact than individual statements in a function.
Also: was it difficult to switch from Fancy Magic bitboards to PEXT bitboards (didn't look into them yet), and was it worth it? Do you do one or more optimizations in the move generator? As Crafty runs slower on your system than it does on mine, I assume you have slower CPU; but still, on that slower CPU, Weiss is 10 seconds faster than Rustic is on my CPU.
Startpos perft 8:
Code: Select all
lastemperor -hash 1024 -perft 8
[ rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1 ]
Depth Nodes Mnps Time
0 1 0.000 0.000
1 20 0.000 0.000
2 400 0.000 0.000
3 8,902 8.902 0.001
4 197,281 10.383 0.019
5 4,865,609 19.619 0.248
6 119,060,324 42.041 2.832
7 3,195,901,860 97.998 32.612
8 84,998,978,956 188.695 450.456
=================================================
Nodes Mnps Time
Total 88,319,013,353 181.664 486.168
Code: Select all
lastemperor -fen "r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10 " -hash 1024 -perft 6
[ r4rk1/1pp1qppp/p1np1n2/2b1p1B1/2B1P1b1/P1NP1N2/1PP1QPPP/R4RK1 w - - 0 10 ]
Depth Nodes Mnps Time
0 1 0.000 0.000
1 46 0.000 0.000
2 2,079 2.079 0.001
3 89,890 22.472 0.004
4 3,894,594 21.758 0.179
5 164,075,551 58.452 2.807
6 6,923,051,137 110.546 62.626
=================================================
Nodes Mnps Time
Total 7,091,113,298 108.068 65.617
Code: Select all
lastemperor -fen "rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8 " -hash 1024 -perft 6
[ rnbq1k1r/pp1Pbppp/2p5/8/2B5/8/PPP1NnPP/RNBQK2R w KQ - 1 8 ]
Depth Nodes Mnps Time
0 1 0.000 0.000
1 44 0.000 0.000
2 1,486 0.000 0.000
3 62,379 12.476 0.005
4 2,103,487 17.529 0.120
5 89,941,194 41.409 2.172
6 3,048,196,529 68.593 44.439
=================================================
Nodes Mnps Time
Total 3,140,305,120 67.192 46.736