You continuously keep screaming "wrong" against everything everyone on here says. It's getting annoying.dangi12012 wrote: ↑Sat Oct 16, 2021 12:11 pm Wrong. That is only the case if the compiler can infer what sq is. Like if you use it in a for loop - but its exectly opposite if you use a not compiletime known value - like when you are deep in a calculation - then the compiler will emit that array into some memory location and you have a L1 lookup for [sq] but register calculation for <<.
Its 100% verifyably slower - just test it with random numbers![]()
The const fn builds a constant array. For the Rust compiler it is no difference if you say:
Code: Select all
x = (1u64 << sq) & stuff // direct shift
Code: Select all
x = BB_SQUARES[sq] & stuff // pre-calculated
Code: Select all
x = bb_squares(sq) & stuff // contains the calculation of the first option
Maybe there are some situations where "1u64 << x" is faster than indexing into a constant SQUARES[x] array, but for a chess engine, at least in Rust, it makes no difference. I tested it myself yesterday, because Rustic uses the mask[sq] option (where mask is a const array, filled by a const fn function), and I replaced it by by a function that does a shift. In the end I replaced that by things such as "BB_RANK1 << rank" etc; so I didn't do it for squares only, but also for ranks and files. All thee options are completely equal.
I can understand that, if you store a normal array of random numbers in memory and then start indexing it, that this is slower than directly shifting the bits on the original number. However, that's not what happens in a chess engine. In a chess engine, all information is always known. Even the random numbers aren't random because they're either generated to always yield the same set, or actually pasted into the code.
That's also the reason why I often say: "doesn't make a difference _in a chess engine_", because a chess engine, at the very core, is only a tree walker which scores nodes using an evaluation function and finds the most optimal path (= best move for each side) through the tree. The rest is only techniques on cutting down on the tree, scoring the nodes better/more accurately, and obviously a way to generate the nodes in real-time because we can't build a computer large enough to just generate the entire tree, score the entire thing, and then find the optimal path; which would thus solve chess.
It has been done for draughts and/or checkers, though. In that game, the optimal path between a large opening book and an endgame tablebase is known.