diff --git a/src/search.cpp b/src/search.cpp index 40ba2effa..44cd97c91 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -114,13 +114,14 @@ void update_correction_history(const Position& pos, shared.nonpawn_correction_entry(pos).at(us).nonPawnWhite << bonus * nonPawnWeight / 128; shared.nonpawn_correction_entry(pos).at(us).nonPawnBlack << bonus * nonPawnWeight / 128; - if (m.is_ok()) - { - const Square to = m.to_sq(); - const Piece pc = pos.piece_on(m.to_sq()); - (*(ss - 2)->continuationCorrectionHistory)[pc][to] << bonus * 127 / 128; - (*(ss - 4)->continuationCorrectionHistory)[pc][to] << bonus * 59 / 128; - } + // Branchless: use mask to zero bonus when move is not ok + const int mask = int(m.is_ok()); + const Square to = m.to_sq_unchecked(); + const Piece pc = pos.piece_on(to); + const int bonus2 = (bonus * 127 / 128) * mask; + const int bonus4 = (bonus * 59 / 128) * mask; + (*(ss - 2)->continuationCorrectionHistory)[pc][to] << bonus2; + (*(ss - 4)->continuationCorrectionHistory)[pc][to] << bonus4; } // Add a small random component to draw evaluations to avoid 3-fold blindness diff --git a/src/types.h b/src/types.h index 10a0d1ac5..bfaa658e9 100644 --- a/src/types.h +++ b/src/types.h @@ -449,6 +449,10 @@ class Move { return Square(data & 0x3F); } + // Same as to_sq() but without assertion, for branchless code paths + // where the result is masked/ignored when move is not ok + constexpr Square to_sq_unchecked() const { return Square(data & 0x3F); } + constexpr MoveType type_of() const { return MoveType(data & (3 << 14)); } constexpr PieceType promotion_type() const { return PieceType(((data >> 12) & 3) + KNIGHT); }