Simplify indexing

Removes 1 function (from_to) from the Move type, change them to simpler raw.
Remove the "and" use in the correction history structure calculation. Adjust
the indexing.

Passed simplification STC:
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 42880 W: 11327 L: 11113 D: 20440
Ptnml(0-2): 161, 4852, 11212, 5042, 173
https://tests.stockfishchess.org/tests/view/690593b8ea4b268f1fac1e8a

Passed simplification LTC:
LLR: 2.94 (-2.94,2.94) <-1.75,0.25>
Total: 43560 W: 11276 L: 11079 D: 21205
Ptnml(0-2): 17, 4679, 12197, 4864, 23
https://tests.stockfishchess.org/tests/view/6906f819ea4b268f1fac216b

closes https://github.com/official-stockfish/Stockfish/pull/6391

Bench: 2523092
This commit is contained in:
AliceRoselia
2025-11-14 17:28:17 +01:00
committed by Joost VandeVondele
parent df88db16c6
commit 7b7a9485d6
4 changed files with 21 additions and 28 deletions
+11 -16
View File
@@ -33,32 +33,28 @@
namespace Stockfish {
constexpr int PAWN_HISTORY_SIZE = 8192; // has to be a power of 2
constexpr int CORRECTION_HISTORY_SIZE = 32768; // has to be a power of 2
constexpr int PAWN_HISTORY_SIZE = 8192; // has to be a power of 2
constexpr int UINT_16_HISTORY_SIZE = std::numeric_limits<uint16_t>::max() + 1;
constexpr int CORRECTION_HISTORY_LIMIT = 1024;
constexpr int LOW_PLY_HISTORY_SIZE = 5;
static_assert((PAWN_HISTORY_SIZE & (PAWN_HISTORY_SIZE - 1)) == 0,
"PAWN_HISTORY_SIZE has to be a power of 2");
static_assert((CORRECTION_HISTORY_SIZE & (CORRECTION_HISTORY_SIZE - 1)) == 0,
static_assert((UINT_16_HISTORY_SIZE & (UINT_16_HISTORY_SIZE - 1)) == 0,
"CORRECTION_HISTORY_SIZE has to be a power of 2");
inline int pawn_history_index(const Position& pos) {
return pos.pawn_key() & (PAWN_HISTORY_SIZE - 1);
}
inline int pawn_correction_history_index(const Position& pos) {
return pos.pawn_key() & (CORRECTION_HISTORY_SIZE - 1);
}
inline uint16_t pawn_correction_history_index(const Position& pos) { return pos.pawn_key(); }
inline int minor_piece_index(const Position& pos) {
return pos.minor_piece_key() & (CORRECTION_HISTORY_SIZE - 1);
}
inline uint16_t minor_piece_index(const Position& pos) { return pos.minor_piece_key(); }
template<Color c>
inline int non_pawn_index(const Position& pos) {
return pos.non_pawn_key(c) & (CORRECTION_HISTORY_SIZE - 1);
inline uint16_t non_pawn_index(const Position& pos) {
return pos.non_pawn_key(c);
}
// StatsEntry is the container of various numerical statistics. We use a class
@@ -102,12 +98,11 @@ using Stats = MultiArray<StatsEntry<T, D>, Sizes...>;
// during the current search, and is used for reduction and move ordering decisions.
// It uses 2 tables (one for each color) indexed by the move's from and to squares,
// see https://www.chessprogramming.org/Butterfly_Boards
using ButterflyHistory = Stats<std::int16_t, 7183, COLOR_NB, int(SQUARE_NB) * int(SQUARE_NB)>;
using ButterflyHistory = Stats<std::int16_t, 7183, COLOR_NB, UINT_16_HISTORY_SIZE>;
// LowPlyHistory is addressed by play and move's from and to squares, used
// to improve move ordering near the root
using LowPlyHistory =
Stats<std::int16_t, 7183, LOW_PLY_HISTORY_SIZE, int(SQUARE_NB) * int(SQUARE_NB)>;
using LowPlyHistory = Stats<std::int16_t, 7183, LOW_PLY_HISTORY_SIZE, UINT_16_HISTORY_SIZE>;
// CapturePieceToHistory is addressed by a move's [piece][to][captured piece type]
using CapturePieceToHistory = Stats<std::int16_t, 10692, PIECE_NB, SQUARE_NB, PIECE_TYPE_NB>;
@@ -139,7 +134,7 @@ namespace Detail {
template<CorrHistType>
struct CorrHistTypedef {
using type = Stats<std::int16_t, CORRECTION_HISTORY_LIMIT, CORRECTION_HISTORY_SIZE, COLOR_NB>;
using type = Stats<std::int16_t, CORRECTION_HISTORY_LIMIT, UINT_16_HISTORY_SIZE, COLOR_NB>;
};
template<>
@@ -155,7 +150,7 @@ struct CorrHistTypedef<Continuation> {
template<>
struct CorrHistTypedef<NonPawn> {
using type =
Stats<std::int16_t, CORRECTION_HISTORY_LIMIT, CORRECTION_HISTORY_SIZE, COLOR_NB, COLOR_NB>;
Stats<std::int16_t, CORRECTION_HISTORY_LIMIT, UINT_16_HISTORY_SIZE, COLOR_NB, COLOR_NB>;
};
}
+4 -4
View File
@@ -158,7 +158,7 @@ ExtMove* MovePicker::score(MoveList<Type>& ml) {
else if constexpr (Type == QUIETS)
{
// histories
m.value = 2 * (*mainHistory)[us][m.from_to()];
m.value = 2 * (*mainHistory)[us][m.raw()];
m.value += 2 * (*pawnHistory)[pawn_history_index(pos)][pc][to];
m.value += (*continuationHistory[0])[pc][to];
m.value += (*continuationHistory[1])[pc][to];
@@ -176,7 +176,7 @@ ExtMove* MovePicker::score(MoveList<Type>& ml) {
if (ply < LOW_PLY_HISTORY_SIZE)
m.value += 8 * (*lowPlyHistory)[ply][m.from_to()] / (1 + ply);
m.value += 8 * (*lowPlyHistory)[ply][m.raw()] / (1 + ply);
}
else // Type == EVASIONS
@@ -185,9 +185,9 @@ ExtMove* MovePicker::score(MoveList<Type>& ml) {
m.value = PieceValue[capturedPiece] + (1 << 28);
else
{
m.value = (*mainHistory)[us][m.from_to()] + (*continuationHistory[0])[pc][to];
m.value = (*mainHistory)[us][m.raw()] + (*continuationHistory[0])[pc][to];
if (ply < LOW_PLY_HISTORY_SIZE)
m.value += (*lowPlyHistory)[ply][m.from_to()];
m.value += (*lowPlyHistory)[ply][m.raw()];
}
}
}
+6 -6
View File
@@ -824,7 +824,7 @@ Value Search::Worker::search(
if (((ss - 1)->currentMove).is_ok() && !(ss - 1)->inCheck && !priorCapture)
{
int evalDiff = std::clamp(-int((ss - 1)->staticEval + ss->staticEval), -200, 156) + 58;
mainHistory[~us][((ss - 1)->currentMove).from_to()] << evalDiff * 9;
mainHistory[~us][((ss - 1)->currentMove).raw()] << evalDiff * 9;
if (!ttHit && type_of(pos.piece_on(prevSq)) != PAWN
&& ((ss - 1)->currentMove).type_of() != PROMOTION)
pawnHistory[pawn_history_index(pos)][pos.piece_on(prevSq)][prevSq] << evalDiff * 14;
@@ -1066,7 +1066,7 @@ moves_loop: // When in check, search starts here
if (history < -4312 * depth)
continue;
history += 76 * mainHistory[us][move.from_to()] / 32;
history += 76 * mainHistory[us][move.raw()] / 32;
// (*Scaler): Generally, a lower divisor scales well
lmrDepth += history / 3220;
@@ -1196,7 +1196,7 @@ moves_loop: // When in check, search starts here
ss->statScore = 803 * int(PieceValue[pos.captured_piece()]) / 128
+ captureHistory[movedPiece][move.to_sq()][type_of(pos.captured_piece())];
else
ss->statScore = 2 * mainHistory[us][move.from_to()]
ss->statScore = 2 * mainHistory[us][move.raw()]
+ (*contHist[0])[movedPiece][move.to_sq()]
+ (*contHist[1])[movedPiece][move.to_sq()];
@@ -1414,7 +1414,7 @@ moves_loop: // When in check, search starts here
update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq,
scaledBonus * 400 / 32768);
mainHistory[~us][((ss - 1)->currentMove).from_to()] << scaledBonus * 220 / 32768;
mainHistory[~us][((ss - 1)->currentMove).raw()] << scaledBonus * 220 / 32768;
if (type_of(pos.piece_on(prevSq)) != PAWN && ((ss - 1)->currentMove).type_of() != PROMOTION)
pawnHistory[pawn_history_index(pos)][pos.piece_on(prevSq)][prevSq]
@@ -1862,10 +1862,10 @@ void update_quiet_histories(
const Position& pos, Stack* ss, Search::Worker& workerThread, Move move, int bonus) {
Color us = pos.side_to_move();
workerThread.mainHistory[us][move.from_to()] << bonus; // Untuned to prevent duplicate effort
workerThread.mainHistory[us][move.raw()] << bonus; // Untuned to prevent duplicate effort
if (ss->ply < LOW_PLY_HISTORY_SIZE)
workerThread.lowPlyHistory[ss->ply][move.from_to()] << bonus * 761 / 1024;
workerThread.lowPlyHistory[ss->ply][move.raw()] << bonus * 761 / 1024;
update_continuation_histories(ss, pos.moved_piece(move), move.to_sq(), bonus * 955 / 1024);
-2
View File
@@ -448,8 +448,6 @@ class Move {
return Square(data & 0x3F);
}
constexpr int from_to() const { return data & 0xFFF; }
constexpr MoveType type_of() const { return MoveType(data & (3 << 14)); }
constexpr PieceType promotion_type() const { return PieceType(((data >> 12) & 3) + KNIGHT); }