Henk wrote:Also after you have extracted a bit of a move you still have to look up the corresponding move in a dictionary.
Look up what?
You have the "from" square where you started to generated moves for, and you have found a bit position which is exactly the "to" square. What else do you need to look up? All moves, except for the few special move types, only need the "from" and "to" squares to be fully defined.
How does your move representation look like?
My engine only generates moves once and moves are pre-calculated so I have to look them up. Also I assigned a unique number to each move for storing it into a database.
Sorry last is not true. I compute that unique number from the move.
So only argument is that I don't want to create a new move each time. Also for testing if moves are equal I only need to compare the references.
Henk wrote:Also after you have extracted a bit of a move you still have to look up the corresponding move in a dictionary.
Look up what?
You have the "from" square where you started to generated moves for, and you have found a bit position which is exactly the "to" square. What else do you need to look up? All moves, except for the few special move types, only need the "from" and "to" squares to be fully defined.
How does your move representation look like?
My engine only generates moves once and moves are pre-calculated so I have to look them up. Also I assigned a unique number to each move for storing it into a database.
Sorry last is not true. I compute that unique number from the move.
So only argument is that I don't want to create a new move each time. Also for testing if moves are equal I only need to compare the references.
Well, that is certainly one way to go, albeit a slow one ...
My move representation is 16 bit (6 bit "from", 6 bit "to", 2 bit for one of four move types, and 2 bit for special purpose depending on move type: either the castling type, the promotion piece, or a flag indicating a pawn double step). Plus 16 bit for the move score, for a total of 32 bit. So my move is just an integer, "creating" it is just masking/shifting some bits.
But even a larger move representation does not require "creation" of a move object each time you generate a new move. I would simply preallocate a move list as an array of fixed length, 256 is a safe upper bound for the length.
Put that on your "optimization" to-do list for next year, after having improved your algorithms
Henk wrote:Changed pawns and king captures too. Only 1-3 percent faster. Hardly measurable. Pawns spoiled the party. Also because I had to make an exception for En Passant moves. Might be that code for handling pawn captures is slower now.
case ChessPiece.Sort.whiteQueen:
case ChessPiece.Sort.blackQueen:
case ChessPiece.Sort.whiteRook:
case ChessPiece.Sort.blackRook:
case ChessPiece.Sort.whiteBishop:
case ChessPiece.Sort.blackBishop:
for (dir = 0; dir <= pieceOffsets[occupier.PieceKind].Length-1; dir++)
{
ulong moveBit = ((SlidingPiece)occupier).BitBoardDirMoves(Board, dir, xrayCaptures);
if (moveBit != 0)
{
var move = ((Field)location).AllMovesDict(PieceSort).Get(moveBit);
AddMove(moves, move, occupier.PieceKind);
}
}
break;
Henk wrote:Computes/Assigns MVVA value and clears the move list when king capture found.
Do you use the same AddMove() function for both capture and non-capture generation? Would not make sense to me for the non-capture part ...
Henk wrote:Code is now significantly slower perhaps 45 percent.
Are you talking about perft speed or tree search speed? What are you comparing against: before your last specific change XY vs. now, or before starting this thread vs. now, or ...?
I don't know which of the many suggestions that were given here has caused your program to perform even worse than before. My focus was not on optimizing but on an appropriate use of your data structures. In general this should not lead to a significant slowdown. If it does then I don't know as well - too many possible reasons for that: bugs, sub-optimal data structures, misinterpretation of some suggestions that were made, maybe even sub-optimal suggestions, ...
I think implementation of BitBoardDirMoves is too slow. So I have to look at that first. I can always restore the old code without bitboards. Ugly and fast.
Only last change in QCollectMoves dealing with sliding piece captures made it slow.
Henk wrote:I think implementation of BitBoardDirMoves is too slow. So I have to look at that first. I can always restore the old code without bitboards. Ugly and fast.
Only last change in QCollectMoves dealing with sliding piece captures made it slow.