mirror of
https://github.com/opelly27/Stockfish.git
synced 2026-05-20 02:47:45 +00:00
Refactor root history into low ply history
This patch changes root history to low ply history - butterfly history for plies < 4. Doubles weight of this history for root, latter plies have lesser effect. Passed STC: https://tests.stockfishchess.org/tests/view/66f77d2386d5ee47d953b65d LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 180992 W: 47362 L: 46830 D: 86800 Ptnml(0-2): 554, 21499, 45928, 21891, 624 Passed LTC: https://tests.stockfishchess.org/tests/view/66fb557986d5ee47d953b8e5 LLR: 2.95 (-2.94,2.94) <0.50,2.50> Total: 42462 W: 11013 L: 10682 D: 20767 Ptnml(0-2): 33, 4518, 11795, 4855, 30 closes https://github.com/official-stockfish/Stockfish/pull/5614 Bench 1264335
This commit is contained in:
committed by
Joost VandeVondele
parent
0186904f53
commit
7ac745a736
+6
-6
@@ -82,20 +82,20 @@ MovePicker::MovePicker(const Position& p,
|
|||||||
Move ttm,
|
Move ttm,
|
||||||
Depth d,
|
Depth d,
|
||||||
const ButterflyHistory* mh,
|
const ButterflyHistory* mh,
|
||||||
const ButterflyHistory* rh,
|
const LowPlyHistory* lph,
|
||||||
const CapturePieceToHistory* cph,
|
const CapturePieceToHistory* cph,
|
||||||
const PieceToHistory** ch,
|
const PieceToHistory** ch,
|
||||||
const PawnHistory* ph,
|
const PawnHistory* ph,
|
||||||
bool rn) :
|
int pl) :
|
||||||
pos(p),
|
pos(p),
|
||||||
mainHistory(mh),
|
mainHistory(mh),
|
||||||
rootHistory(rh),
|
lowPlyHistory(lph),
|
||||||
captureHistory(cph),
|
captureHistory(cph),
|
||||||
continuationHistory(ch),
|
continuationHistory(ch),
|
||||||
pawnHistory(ph),
|
pawnHistory(ph),
|
||||||
ttMove(ttm),
|
ttMove(ttm),
|
||||||
depth(d),
|
depth(d),
|
||||||
rootNode(rn) {
|
ply(pl) {
|
||||||
|
|
||||||
if (pos.checkers())
|
if (pos.checkers())
|
||||||
stage = EVASION_TT + !(ttm && pos.pseudo_legal(ttm));
|
stage = EVASION_TT + !(ttm && pos.pseudo_legal(ttm));
|
||||||
@@ -179,8 +179,8 @@ void MovePicker::score() {
|
|||||||
: pt == ROOK && bool(to & threatenedByMinor) ? 24335
|
: pt == ROOK && bool(to & threatenedByMinor) ? 24335
|
||||||
: 0);
|
: 0);
|
||||||
|
|
||||||
if (rootNode)
|
if (ply < 4)
|
||||||
m.value += 4 * (*rootHistory)[pos.side_to_move()][m.from_to()];
|
m.value += 8 * (*lowPlyHistory)[ply][m.from_to()] / (1 + 2 * ply);
|
||||||
}
|
}
|
||||||
|
|
||||||
else // Type == EVASIONS
|
else // Type == EVASIONS
|
||||||
|
|||||||
+8
-4
@@ -135,6 +135,10 @@ enum StatsType {
|
|||||||
// see https://www.chessprogramming.org/Butterfly_Boards (~11 elo)
|
// see https://www.chessprogramming.org/Butterfly_Boards (~11 elo)
|
||||||
using ButterflyHistory = Stats<int16_t, 7183, COLOR_NB, int(SQUARE_NB) * int(SQUARE_NB)>;
|
using ButterflyHistory = Stats<int16_t, 7183, COLOR_NB, int(SQUARE_NB) * int(SQUARE_NB)>;
|
||||||
|
|
||||||
|
// LowPlyHistory is adressed by play and move's from and to squares, used
|
||||||
|
// to improve move ordering near the root
|
||||||
|
using LowPlyHistory = Stats<int16_t, 7183, 4, int(SQUARE_NB) * int(SQUARE_NB)>;
|
||||||
|
|
||||||
// CapturePieceToHistory is addressed by a move's [piece][to][captured piece type]
|
// CapturePieceToHistory is addressed by a move's [piece][to][captured piece type]
|
||||||
using CapturePieceToHistory = Stats<int16_t, 10692, PIECE_NB, SQUARE_NB, PIECE_TYPE_NB>;
|
using CapturePieceToHistory = Stats<int16_t, 10692, PIECE_NB, SQUARE_NB, PIECE_TYPE_NB>;
|
||||||
|
|
||||||
@@ -195,11 +199,11 @@ class MovePicker {
|
|||||||
Move,
|
Move,
|
||||||
Depth,
|
Depth,
|
||||||
const ButterflyHistory*,
|
const ButterflyHistory*,
|
||||||
const ButterflyHistory*,
|
const LowPlyHistory*,
|
||||||
const CapturePieceToHistory*,
|
const CapturePieceToHistory*,
|
||||||
const PieceToHistory**,
|
const PieceToHistory**,
|
||||||
const PawnHistory*,
|
const PawnHistory*,
|
||||||
bool);
|
int);
|
||||||
MovePicker(const Position&, Move, int, const CapturePieceToHistory*);
|
MovePicker(const Position&, Move, int, const CapturePieceToHistory*);
|
||||||
Move next_move(bool skipQuiets = false);
|
Move next_move(bool skipQuiets = false);
|
||||||
|
|
||||||
@@ -213,7 +217,7 @@ class MovePicker {
|
|||||||
|
|
||||||
const Position& pos;
|
const Position& pos;
|
||||||
const ButterflyHistory* mainHistory;
|
const ButterflyHistory* mainHistory;
|
||||||
const ButterflyHistory* rootHistory;
|
const LowPlyHistory* lowPlyHistory;
|
||||||
const CapturePieceToHistory* captureHistory;
|
const CapturePieceToHistory* captureHistory;
|
||||||
const PieceToHistory** continuationHistory;
|
const PieceToHistory** continuationHistory;
|
||||||
const PawnHistory* pawnHistory;
|
const PawnHistory* pawnHistory;
|
||||||
@@ -222,7 +226,7 @@ class MovePicker {
|
|||||||
int stage;
|
int stage;
|
||||||
int threshold;
|
int threshold;
|
||||||
Depth depth;
|
Depth depth;
|
||||||
bool rootNode;
|
int ply;
|
||||||
ExtMove moves[MAX_MOVES];
|
ExtMove moves[MAX_MOVES];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
+25
-37
@@ -105,21 +105,16 @@ Value value_to_tt(Value v, int ply);
|
|||||||
Value value_from_tt(Value v, int ply, int r50c);
|
Value value_from_tt(Value v, int ply, int r50c);
|
||||||
void update_pv(Move* pv, Move move, const Move* childPv);
|
void update_pv(Move* pv, Move move, const Move* childPv);
|
||||||
void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
|
void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus);
|
||||||
void update_quiet_histories(const Position& pos,
|
void update_quiet_histories(
|
||||||
Stack* ss,
|
const Position& pos, Stack* ss, Search::Worker& workerThread, Move move, int bonus);
|
||||||
Search::Worker& workerThread,
|
void update_all_stats(const Position& pos,
|
||||||
Move move,
|
Stack* ss,
|
||||||
int bonus,
|
Search::Worker& workerThread,
|
||||||
bool rootNode);
|
Move bestMove,
|
||||||
void update_all_stats(const Position& pos,
|
Square prevSq,
|
||||||
Stack* ss,
|
ValueList<Move, 32>& quietsSearched,
|
||||||
Search::Worker& workerThread,
|
ValueList<Move, 32>& capturesSearched,
|
||||||
Move bestMove,
|
Depth depth);
|
||||||
Square prevSq,
|
|
||||||
ValueList<Move, 32>& quietsSearched,
|
|
||||||
ValueList<Move, 32>& capturesSearched,
|
|
||||||
Depth depth,
|
|
||||||
bool rootNode);
|
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
@@ -273,7 +268,7 @@ void Search::Worker::iterative_deepening() {
|
|||||||
|
|
||||||
int searchAgainCounter = 0;
|
int searchAgainCounter = 0;
|
||||||
|
|
||||||
rootHistory.fill(0);
|
lowPlyHistory.fill(0);
|
||||||
|
|
||||||
// Iterative deepening loop until requested to stop or the target depth is reached
|
// Iterative deepening loop until requested to stop or the target depth is reached
|
||||||
while (++rootDepth < MAX_PLY && !threads.stop
|
while (++rootDepth < MAX_PLY && !threads.stop
|
||||||
@@ -499,7 +494,7 @@ void Search::Worker::iterative_deepening() {
|
|||||||
// Reset histories, usually before a new game
|
// Reset histories, usually before a new game
|
||||||
void Search::Worker::clear() {
|
void Search::Worker::clear() {
|
||||||
mainHistory.fill(0);
|
mainHistory.fill(0);
|
||||||
rootHistory.fill(0);
|
lowPlyHistory.fill(0);
|
||||||
captureHistory.fill(-753);
|
captureHistory.fill(-753);
|
||||||
pawnHistory.fill(-1152);
|
pawnHistory.fill(-1152);
|
||||||
pawnCorrectionHistory.fill(0);
|
pawnCorrectionHistory.fill(0);
|
||||||
@@ -638,7 +633,7 @@ Value Search::Worker::search(
|
|||||||
{
|
{
|
||||||
// Bonus for a quiet ttMove that fails high (~2 Elo)
|
// Bonus for a quiet ttMove that fails high (~2 Elo)
|
||||||
if (!ttCapture)
|
if (!ttCapture)
|
||||||
update_quiet_histories(pos, ss, *this, ttData.move, stat_bonus(depth), rootNode);
|
update_quiet_histories(pos, ss, *this, ttData.move, stat_bonus(depth));
|
||||||
|
|
||||||
// Extra penalty for early quiet moves of
|
// Extra penalty for early quiet moves of
|
||||||
// the previous ply (~1 Elo on STC, ~2 Elo on LTC)
|
// the previous ply (~1 Elo on STC, ~2 Elo on LTC)
|
||||||
@@ -928,8 +923,8 @@ moves_loop: // When in check, search starts here
|
|||||||
(ss - 6)->continuationHistory};
|
(ss - 6)->continuationHistory};
|
||||||
|
|
||||||
|
|
||||||
MovePicker mp(pos, ttData.move, depth, &thisThread->mainHistory, &thisThread->rootHistory,
|
MovePicker mp(pos, ttData.move, depth, &thisThread->mainHistory, &thisThread->lowPlyHistory,
|
||||||
&thisThread->captureHistory, contHist, &thisThread->pawnHistory, rootNode);
|
&thisThread->captureHistory, contHist, &thisThread->pawnHistory, ss->ply);
|
||||||
|
|
||||||
value = bestValue;
|
value = bestValue;
|
||||||
|
|
||||||
@@ -1355,8 +1350,7 @@ moves_loop: // When in check, search starts here
|
|||||||
// If there is a move that produces search value greater than alpha,
|
// If there is a move that produces search value greater than alpha,
|
||||||
// we update the stats of searched moves.
|
// we update the stats of searched moves.
|
||||||
else if (bestMove)
|
else if (bestMove)
|
||||||
update_all_stats(pos, ss, *this, bestMove, prevSq, quietsSearched, capturesSearched, depth,
|
update_all_stats(pos, ss, *this, bestMove, prevSq, quietsSearched, capturesSearched, depth);
|
||||||
rootNode);
|
|
||||||
|
|
||||||
// Bonus for prior countermove that caused the fail low
|
// Bonus for prior countermove that caused the fail low
|
||||||
else if (!priorCapture && prevSq != SQ_NONE)
|
else if (!priorCapture && prevSq != SQ_NONE)
|
||||||
@@ -1557,9 +1551,8 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta)
|
|||||||
// Initialize a MovePicker object for the current position, and prepare to search
|
// Initialize a MovePicker object for the current position, and prepare to search
|
||||||
// the moves. We presently use two stages of move generator in quiescence search:
|
// the moves. We presently use two stages of move generator in quiescence search:
|
||||||
// captures, or evasions only when in check.
|
// captures, or evasions only when in check.
|
||||||
MovePicker mp(pos, ttData.move, DEPTH_QS, &thisThread->mainHistory, &thisThread->rootHistory,
|
MovePicker mp(pos, ttData.move, DEPTH_QS, &thisThread->mainHistory, &thisThread->lowPlyHistory,
|
||||||
&thisThread->captureHistory, contHist, &thisThread->pawnHistory,
|
&thisThread->captureHistory, contHist, &thisThread->pawnHistory, ss->ply);
|
||||||
nodeType == Root);
|
|
||||||
|
|
||||||
// Step 5. Loop through all pseudo-legal moves until no moves remain or a beta
|
// Step 5. Loop through all pseudo-legal moves until no moves remain or a beta
|
||||||
// cutoff occurs.
|
// cutoff occurs.
|
||||||
@@ -1768,8 +1761,7 @@ void update_all_stats(const Position& pos,
|
|||||||
Square prevSq,
|
Square prevSq,
|
||||||
ValueList<Move, 32>& quietsSearched,
|
ValueList<Move, 32>& quietsSearched,
|
||||||
ValueList<Move, 32>& capturesSearched,
|
ValueList<Move, 32>& capturesSearched,
|
||||||
Depth depth,
|
Depth depth) {
|
||||||
bool rootNode) {
|
|
||||||
|
|
||||||
CapturePieceToHistory& captureHistory = workerThread.captureHistory;
|
CapturePieceToHistory& captureHistory = workerThread.captureHistory;
|
||||||
Piece moved_piece = pos.moved_piece(bestMove);
|
Piece moved_piece = pos.moved_piece(bestMove);
|
||||||
@@ -1780,11 +1772,11 @@ void update_all_stats(const Position& pos,
|
|||||||
|
|
||||||
if (!pos.capture_stage(bestMove))
|
if (!pos.capture_stage(bestMove))
|
||||||
{
|
{
|
||||||
update_quiet_histories(pos, ss, workerThread, bestMove, quietMoveBonus, rootNode);
|
update_quiet_histories(pos, ss, workerThread, bestMove, quietMoveBonus);
|
||||||
|
|
||||||
// Decrease stats for all non-best quiet moves
|
// Decrease stats for all non-best quiet moves
|
||||||
for (Move move : quietsSearched)
|
for (Move move : quietsSearched)
|
||||||
update_quiet_histories(pos, ss, workerThread, move, -quietMoveMalus, rootNode);
|
update_quiet_histories(pos, ss, workerThread, move, -quietMoveMalus);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -1826,17 +1818,13 @@ void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus) {
|
|||||||
|
|
||||||
// Updates move sorting heuristics
|
// Updates move sorting heuristics
|
||||||
|
|
||||||
void update_quiet_histories(const Position& pos,
|
void update_quiet_histories(
|
||||||
Stack* ss,
|
const Position& pos, Stack* ss, Search::Worker& workerThread, Move move, int bonus) {
|
||||||
Search::Worker& workerThread,
|
|
||||||
Move move,
|
|
||||||
int bonus,
|
|
||||||
bool rootNode) {
|
|
||||||
|
|
||||||
Color us = pos.side_to_move();
|
Color us = pos.side_to_move();
|
||||||
workerThread.mainHistory[us][move.from_to()] << bonus;
|
workerThread.mainHistory[us][move.from_to()] << bonus;
|
||||||
if (rootNode)
|
if (ss->ply < 4)
|
||||||
workerThread.rootHistory[us][move.from_to()] << bonus;
|
workerThread.lowPlyHistory[ss->ply][move.from_to()] << bonus;
|
||||||
|
|
||||||
update_continuation_histories(ss, pos.moved_piece(move), move.to_sq(), bonus);
|
update_continuation_histories(ss, pos.moved_piece(move), move.to_sq(), bonus);
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -278,7 +278,7 @@ class Worker {
|
|||||||
|
|
||||||
// Public because they need to be updatable by the stats
|
// Public because they need to be updatable by the stats
|
||||||
ButterflyHistory mainHistory;
|
ButterflyHistory mainHistory;
|
||||||
ButterflyHistory rootHistory;
|
LowPlyHistory lowPlyHistory;
|
||||||
|
|
||||||
CapturePieceToHistory captureHistory;
|
CapturePieceToHistory captureHistory;
|
||||||
ContinuationHistory continuationHistory[2][2];
|
ContinuationHistory continuationHistory[2][2];
|
||||||
|
|||||||
Reference in New Issue
Block a user