Skip to content

Commit

Permalink
Change from [Color][PieceType] to [Piece]
Browse files Browse the repository at this point in the history
Speed up of almost 1% in both normal and
pgo builds.

No functional change.
  • Loading branch information
syzygy authored and mcostalba committed Sep 4, 2016
1 parent c5828c4 commit ca6c9f8
Show file tree
Hide file tree
Showing 6 changed files with 124 additions and 119 deletions.
135 changes: 68 additions & 67 deletions src/position.cpp
Expand Up @@ -36,7 +36,7 @@ using std::string;

namespace Zobrist {

Key psq[COLOR_NB][PIECE_TYPE_NB][SQUARE_NB];
Key psq[PIECE_NB][SQUARE_NB];
Key enpassant[FILE_NB];
Key castling[CASTLING_RIGHT_NB];
Key side;
Expand Down Expand Up @@ -112,7 +112,7 @@ void Position::init() {
for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt)
for (Square s = SQ_A1; s <= SQ_H8; ++s)
Zobrist::psq[c][pt][s] = rng.rand<Key>();
Zobrist::psq[make_piece(c, pt)][s] = rng.rand<Key>();

for (File f = FILE_A; f <= FILE_H; ++f)
Zobrist::enpassant[f] = rng.rand<Key>();
Expand Down Expand Up @@ -178,7 +178,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th

std::memset(this, 0, sizeof(Position));
std::memset(si, 0, sizeof(StateInfo));
std::fill_n(&pieceList[0][0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
std::fill_n(&pieceList[0][0], sizeof(pieceList) / sizeof(Square), SQ_NONE);
st = si;

ss >> std::noskipws;
Expand All @@ -194,7 +194,7 @@ Position& Position::set(const string& fenStr, bool isChess960, StateInfo* si, Th

else if ((idx = PieceToChar.find(token)) != string::npos)
{
put_piece(color_of(Piece(idx)), type_of(Piece(idx)), sq);
put_piece(Piece(idx), sq);
++sq;
}
}
Expand Down Expand Up @@ -324,8 +324,8 @@ void Position::set_state(StateInfo* si) const {
{
Square s = pop_lsb(&b);
Piece pc = piece_on(s);
si->key ^= Zobrist::psq[color_of(pc)][type_of(pc)][s];
si->psq += PSQT::psq[color_of(pc)][type_of(pc)][s];
si->key ^= Zobrist::psq[pc][s];
si->psq += PSQT::psq[pc][s];
}

if (si->epSquare != SQ_NONE)
Expand All @@ -339,17 +339,17 @@ void Position::set_state(StateInfo* si) const {
for (Bitboard b = pieces(PAWN); b; )
{
Square s = pop_lsb(&b);
si->pawnKey ^= Zobrist::psq[color_of(piece_on(s))][PAWN][s];
si->pawnKey ^= Zobrist::psq[piece_on(s)][s];
}

for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt)
for (int cnt = 0; cnt < pieceCount[c][pt]; ++cnt)
si->materialKey ^= Zobrist::psq[c][pt][cnt];
for (int cnt = 0; cnt < pieceCount[make_piece(c, pt)]; ++cnt)
si->materialKey ^= Zobrist::psq[make_piece(c, pt)][cnt];

for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = KNIGHT; pt <= QUEEN; ++pt)
si->nonPawnMaterial[c] += pieceCount[c][pt] * PieceValue[MG][pt];
si->nonPawnMaterial[c] += pieceCount[make_piece(c, pt)] * PieceValue[MG][pt];
}


Expand Down Expand Up @@ -657,23 +657,24 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
Color them = ~us;
Square from = from_sq(m);
Square to = to_sq(m);
PieceType pt = type_of(piece_on(from));
PieceType captured = type_of(m) == ENPASSANT ? PAWN : type_of(piece_on(to));
Piece pc = piece_on(from);
Piece captured = type_of(m) == ENPASSANT ? make_piece(them, PAWN) : piece_on(to);

assert(color_of(piece_on(from)) == us);
assert(piece_on(to) == NO_PIECE || color_of(piece_on(to)) == (type_of(m) != CASTLING ? them : us));
assert(captured != KING);
assert(color_of(pc) == us);
assert(captured == NO_PIECE || color_of(captured) == (type_of(m) != CASTLING ? them : us));
assert(type_of(captured) != KING);

if (type_of(m) == CASTLING)
{
assert(pt == KING);
assert(pc == make_piece(us, KING));
assert(captured == make_piece(us, ROOK));

Square rfrom, rto;
do_castling<true>(us, from, to, rfrom, rto);

captured = NO_PIECE_TYPE;
st->psq += PSQT::psq[us][ROOK][rto] - PSQT::psq[us][ROOK][rfrom];
k ^= Zobrist::psq[us][ROOK][rfrom] ^ Zobrist::psq[us][ROOK][rto];
st->psq += PSQT::psq[captured][rto] - PSQT::psq[captured][rfrom];
k ^= Zobrist::psq[captured][rfrom] ^ Zobrist::psq[captured][rto];
captured = NO_PIECE;
}

if (captured)
Expand All @@ -682,13 +683,13 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {

// If the captured piece is a pawn, update pawn hash key, otherwise
// update non-pawn material.
if (captured == PAWN)
if (type_of(captured) == PAWN)
{
if (type_of(m) == ENPASSANT)
{
capsq -= pawn_push(us);

assert(pt == PAWN);
assert(pc == make_piece(us, PAWN));
assert(to == st->epSquare);
assert(relative_rank(us, to) == RANK_6);
assert(piece_on(to) == NO_PIECE);
Expand All @@ -697,28 +698,28 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {
board[capsq] = NO_PIECE; // Not done by remove_piece()
}

st->pawnKey ^= Zobrist::psq[them][PAWN][capsq];
st->pawnKey ^= Zobrist::psq[captured][capsq];
}
else
st->nonPawnMaterial[them] -= PieceValue[MG][captured];

// Update board and piece lists
remove_piece(them, captured, capsq);
remove_piece(captured, capsq);

// Update material hash key and prefetch access to materialTable
k ^= Zobrist::psq[them][captured][capsq];
st->materialKey ^= Zobrist::psq[them][captured][pieceCount[them][captured]];
k ^= Zobrist::psq[captured][capsq];
st->materialKey ^= Zobrist::psq[captured][pieceCount[captured]];
prefetch(thisThread->materialTable[st->materialKey]);

// Update incremental scores
st->psq -= PSQT::psq[them][captured][capsq];
st->psq -= PSQT::psq[captured][capsq];

// Reset rule 50 counter
st->rule50 = 0;
}

// Update hash key
k ^= Zobrist::psq[us][pt][from] ^ Zobrist::psq[us][pt][to];
k ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];

// Reset en passant square
if (st->epSquare != SQ_NONE)
Expand All @@ -737,10 +738,10 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {

// Move the piece. The tricky Chess960 castling is handled earlier
if (type_of(m) != CASTLING)
move_piece(us, pt, from, to);
move_piece(pc, from, to);

// If the moving piece is a pawn do some special extra work
if (pt == PAWN)
if (type_of(pc) == PAWN)
{
// Set en-passant square if the moved pawn can be captured
if ( (int(to) ^ int(from)) == 16
Expand All @@ -752,40 +753,40 @@ void Position::do_move(Move m, StateInfo& newSt, bool givesCheck) {

else if (type_of(m) == PROMOTION)
{
PieceType promotion = promotion_type(m);
Piece promotion = make_piece(us, promotion_type(m));

assert(relative_rank(us, to) == RANK_8);
assert(promotion >= KNIGHT && promotion <= QUEEN);
assert(type_of(promotion) >= KNIGHT && type_of(promotion) <= QUEEN);

remove_piece(us, PAWN, to);
put_piece(us, promotion, to);
remove_piece(pc, to);
put_piece(promotion, to);

// Update hash keys
k ^= Zobrist::psq[us][PAWN][to] ^ Zobrist::psq[us][promotion][to];
st->pawnKey ^= Zobrist::psq[us][PAWN][to];
st->materialKey ^= Zobrist::psq[us][promotion][pieceCount[us][promotion]-1]
^ Zobrist::psq[us][PAWN][pieceCount[us][PAWN]];
k ^= Zobrist::psq[pc][to] ^ Zobrist::psq[promotion][to];
st->pawnKey ^= Zobrist::psq[pc][to];
st->materialKey ^= Zobrist::psq[promotion][pieceCount[promotion]-1]
^ Zobrist::psq[pc][pieceCount[pc]];

// Update incremental score
st->psq += PSQT::psq[us][promotion][to] - PSQT::psq[us][PAWN][to];
st->psq += PSQT::psq[promotion][to] - PSQT::psq[pc][to];

// Update material
st->nonPawnMaterial[us] += PieceValue[MG][promotion];
}

// Update pawn hash key and prefetch access to pawnsTable
st->pawnKey ^= Zobrist::psq[us][PAWN][from] ^ Zobrist::psq[us][PAWN][to];
st->pawnKey ^= Zobrist::psq[pc][from] ^ Zobrist::psq[pc][to];
prefetch(thisThread->pawnsTable[st->pawnKey]);

// Reset rule 50 draw counter
st->rule50 = 0;
}

// Update incremental scores
st->psq += PSQT::psq[us][pt][to] - PSQT::psq[us][pt][from];
st->psq += PSQT::psq[pc][to] - PSQT::psq[pc][from];

// Set capture piece
st->capturedType = captured;
st->capturedPiece = captured;

// Update the key with the final value
st->key = k;
Expand Down Expand Up @@ -814,20 +815,20 @@ void Position::undo_move(Move m) {
Color us = sideToMove;
Square from = from_sq(m);
Square to = to_sq(m);
PieceType pt = type_of(piece_on(to));
Piece pc = piece_on(to);

assert(empty(from) || type_of(m) == CASTLING);
assert(st->capturedType != KING);
assert(type_of(st->capturedPiece) != KING);

if (type_of(m) == PROMOTION)
{
assert(relative_rank(us, to) == RANK_8);
assert(pt == promotion_type(m));
assert(pt >= KNIGHT && pt <= QUEEN);
assert(type_of(pc) == promotion_type(m));
assert(type_of(pc) >= KNIGHT && type_of(pc) <= QUEEN);

remove_piece(us, pt, to);
put_piece(us, PAWN, to);
pt = PAWN;
remove_piece(pc, to);
pc = make_piece(us, PAWN);
put_piece(pc, to);
}

if (type_of(m) == CASTLING)
Expand All @@ -837,24 +838,24 @@ void Position::undo_move(Move m) {
}
else
{
move_piece(us, pt, to, from); // Put the piece back at the source square
move_piece(pc, to, from); // Put the piece back at the source square

if (st->capturedType)
if (st->capturedPiece)
{
Square capsq = to;

if (type_of(m) == ENPASSANT)
{
capsq -= pawn_push(us);

assert(pt == PAWN);
assert(type_of(pc) == PAWN);
assert(to == st->previous->epSquare);
assert(relative_rank(us, to) == RANK_6);
assert(piece_on(capsq) == NO_PIECE);
assert(st->capturedType == PAWN);
assert(st->capturedPiece == make_piece(~us, PAWN));
}

put_piece(~us, st->capturedType, capsq); // Restore the captured piece
put_piece(st->capturedPiece, capsq); // Restore the captured piece
}
}

Expand All @@ -867,7 +868,7 @@ void Position::undo_move(Move m) {


/// Position::do_castling() is a helper used to do/undo a castling move. This
/// is a bit tricky, especially in Chess960.
/// is a bit tricky in Chess960 where from/to squares can overlap.
template<bool Do>
void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Square& rto) {

Expand All @@ -877,11 +878,11 @@ void Position::do_castling(Color us, Square from, Square& to, Square& rfrom, Squ
to = relative_square(us, kingSide ? SQ_G1 : SQ_C1);

// Remove both pieces first since squares could overlap in Chess960
remove_piece(us, KING, Do ? from : to);
remove_piece(us, ROOK, Do ? rfrom : rto);
remove_piece(make_piece(us, KING), Do ? from : to);
remove_piece(make_piece(us, ROOK), Do ? rfrom : rto);
board[Do ? from : to] = board[Do ? rfrom : rto] = NO_PIECE; // Since remove_piece doesn't do it for us
put_piece(us, KING, Do ? to : from);
put_piece(us, ROOK, Do ? rto : rfrom);
put_piece(make_piece(us, KING), Do ? to : from);
put_piece(make_piece(us, ROOK), Do ? rto : rfrom);
}


Expand Down Expand Up @@ -931,17 +932,16 @@ void Position::undo_null_move() {

Key Position::key_after(Move m) const {

Color us = sideToMove;
Square from = from_sq(m);
Square to = to_sq(m);
PieceType pt = type_of(piece_on(from));
PieceType captured = type_of(piece_on(to));
Piece pc = piece_on(from);
Piece captured = piece_on(to);
Key k = st->key ^ Zobrist::side;

if (captured)
k ^= Zobrist::psq[~us][captured][to];
k ^= Zobrist::psq[captured][to];

return k ^ Zobrist::psq[us][pt][to] ^ Zobrist::psq[us][pt][from];
return k ^ Zobrist::psq[pc][to] ^ Zobrist::psq[pc][from];
}


Expand Down Expand Up @@ -1139,12 +1139,13 @@ bool Position::pos_is_ok(int* failedStep) const {
for (Color c = WHITE; c <= BLACK; ++c)
for (PieceType pt = PAWN; pt <= KING; ++pt)
{
if (pieceCount[c][pt] != popcount(pieces(c, pt)))
Piece pc = make_piece(c, pt);

if (pieceCount[pc] != popcount(pieces(c, pt)))
return false;

for (int i = 0; i < pieceCount[c][pt]; ++i)
if ( board[pieceList[c][pt][i]] != make_piece(c, pt)
|| index[pieceList[c][pt][i]] != i)
for (int i = 0; i < pieceCount[pc]; ++i)
if (board[pieceList[pc][i]] != pc || index[pieceList[pc][i]] != i)
return false;
}

Expand Down

0 comments on commit ca6c9f8

Please sign in to comment.