From 6bc64416aee663e9bd1321513b0e6f3484e27f6d Mon Sep 17 00:00:00 2001 From: TheRealGioviok <425gioviok@gmail.com> Date: Sun, 18 Oct 2026 21:15:41 +0200 Subject: [PATCH] Bench: 12161447 --- src/history.cpp | 20 ++++++++++++++++++-- src/history.hpp | 21 ++++++++++++++++----- src/search.cpp | 29 ++++++++++++++++++++++++----- src/search.hpp | 3 +++ 4 files changed, 61 insertions(+), 12 deletions(-) diff --git a/src/history.cpp b/src/history.cpp index 70b60076..dc392c2c 100644 --- a/src/history.cpp +++ b/src/history.cpp @@ -89,7 +89,16 @@ void History::update_noisy_stats(const Position& pos, Move move, i32 bonus) { bonus); } -void History::update_correction_history(const Position& pos, i32 depth, i32 diff) { +static i32* get_cont_corr_slot(i32 ply, const Search::Stack* ss) { + if (ply < 2 || (ss - 2)->cont_corr_entry == nullptr || (ss - 1)->move == Move::none()) { + return nullptr; + } + usize prev_pt = static_cast((ss - 1)->moved_piece) - static_cast(PieceType::Pawn); + return &(*(ss - 2)->cont_corr_entry)[prev_pt][(ss - 1)->move.to().raw]; +} + +void History::update_correction_history( + const Position& pos, i32 depth, i32 diff, i32 ply, const Search::Stack* ss) { usize side_index = static_cast(pos.active_color()); u64 pawn_key = pos.get_pawn_key(); u64 white_non_pawn_key = pos.get_non_pawn_key(Color::White); @@ -120,9 +129,12 @@ void History::update_correction_history(const Position& pos, i32 depth, i32 diff update_entry(m_non_pawn_corr_hist[1][side_index][black_non_pawn_index]); update_entry(m_major_corr_hist[side_index][major_index]); update_entry(m_minor_corr_hist[side_index][minor_index]); + if (i32* cont_corr = get_cont_corr_slot(ply, ss)) { + update_entry(*cont_corr); + } } -i32 History::get_correction(const Position& pos) const { +i32 History::get_correction(const Position& pos, i32 ply, const Search::Stack* ss) const { usize side_index = static_cast(pos.active_color()); u64 pawn_key = pos.get_pawn_key(); u64 white_non_pawn_key = pos.get_non_pawn_key(Color::White); @@ -143,6 +155,9 @@ i32 History::get_correction(const Position& pos) const { correction += m_non_pawn_corr_hist[1][side_index][black_non_pawn_index]; correction += m_major_corr_hist[side_index][major_index]; correction += m_minor_corr_hist[side_index][minor_index]; + if (const i32* cont_corr = get_cont_corr_slot(ply, ss)) { + correction += *cont_corr; + } return correction / CORRECTION_HISTORY_GRAIN; } @@ -156,6 +171,7 @@ void History::clear() { std::memset(&m_non_pawn_corr_hist[1], 0, sizeof(CorrectionHistory)); std::memset(&m_major_corr_hist, 0, sizeof(CorrectionHistory)); std::memset(&m_minor_corr_hist, 0, sizeof(CorrectionHistory)); + std::memset(&m_cont_corr_hist, 0, sizeof(ContCorrHistory)); } } // namespace Clockwork diff --git a/src/history.hpp b/src/history.hpp index e1bc71cd..75d4f23f 100644 --- a/src/history.hpp +++ b/src/history.hpp @@ -6,9 +6,11 @@ namespace Clockwork { -using MainHistory = std::array, 4096>, 2>; -using ContHistEntry = std::array, 6>, 2>; -using ContHistory = std::array, 6>, 2>; +using MainHistory = std::array, 4096>, 2>; +using ContHistEntry = std::array, 6>, 2>; +using ContHistory = std::array, 6>, 2>; +using ContCorrEntry = std::array, 6>; +using ContCorrHistory = std::array, 6>, 2>; // king can't get captured using CaptHistory = std::array, 6>, 6>, 2>; using CorrectionHistory = std::array, 2>; @@ -34,6 +36,13 @@ class History { return m_cont_hist[stm_idx][pt_idx][move.to().raw]; } + ContCorrEntry& get_cont_corr_entry(const Position& pos, Move move) { + usize stm_idx = static_cast(pos.active_color()); + PieceType pt = pos.piece_at(move.from()); + usize pt_idx = static_cast(pt) - static_cast(PieceType::Pawn); + return m_cont_corr_hist[stm_idx][pt_idx][move.to().raw]; + } + i32 get_conthist(const Position& pos, Move move, i32 ply, Search::Stack* ss) const; i32 get_quiet_stats(const Position& pos, Move move, i32 ply, Search::Stack* ss) const; void update_cont_hist(const Position& pos, Move move, i32 ply, Search::Stack* ss, i32 bonus); @@ -42,8 +51,9 @@ class History { i32 get_noisy_stats(const Position& pos, Move move) const; void update_noisy_stats(const Position& pos, Move move, i32 bonus); - void update_correction_history(const Position& pos, i32 depth, i32 diff); - i32 get_correction(const Position& pos) const; + void update_correction_history( + const Position& pos, i32 depth, i32 diff, i32 ply, const Search::Stack* ss); + i32 get_correction(const Position& pos, i32 ply, const Search::Stack* ss) const; void clear(); @@ -64,6 +74,7 @@ class History { std::array m_non_pawn_corr_hist = {}; CorrectionHistory m_major_corr_hist = {}; CorrectionHistory m_minor_corr_hist = {}; + ContCorrHistory m_cont_corr_hist = {}; }; } // namespace Clockwork diff --git a/src/search.cpp b/src/search.cpp index a55813b1..5f691fda 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -522,10 +522,10 @@ Value Worker::search( if (alpha < 0 && repetition_info.has_game_cycle(pos, static_cast(ply))) { if (!is_in_check) { auto raw_eval = evaluate(pos); - auto correction = m_td.history.get_correction(pos); + auto correction = m_td.history.get_correction(pos, ply, ss); auto eval = adj_shuffle(pos, raw_eval) + correction; if (eval < 0) { - m_td.history.update_correction_history(pos, depth, -eval); + m_td.history.update_correction_history(pos, depth, -eval, ply, ss); } } @@ -616,7 +616,7 @@ Value Worker::search( Value raw_eval = -VALUE_INF; ss->static_eval = -VALUE_INF; if (!is_in_check) { - correction = excluded ? 0 : m_td.history.get_correction(pos); + correction = excluded ? 0 : m_td.history.get_correction(pos, ply, ss); raw_eval = tt_data && !is_decisive_score(tt_data->eval) ? tt_data->eval : evaluate(pos); ss->static_eval = adj_shuffle(pos, raw_eval) + correction; improving = @@ -711,6 +711,9 @@ Value Worker::search( for (Move m = moves.next(); m != Move::none(); m = moves.next()) { ss->cont_hist_entry = &m_td.history.get_cont_hist_entry(pos, m); + ss->move = m; + ss->moved_piece = pos.piece_at(m.from()); + ss->cont_corr_entry = &m_td.history.get_cont_corr_entry(pos, m); Position pos_after = pos.move(m, m_td.push_psqt_state(), &m_searcher.tt); repetition_info.push(pos_after.get_hash_key(), pos.is_reversible(m)); @@ -726,6 +729,9 @@ Value Worker::search( repetition_info.pop(); m_td.pop_psqt_state(); ss->cont_hist_entry = nullptr; + ss->move = Move::none(); + ss->moved_piece = PieceType::None; + ss->cont_corr_entry = nullptr; if (probcut_value >= probcut_beta) { m_searcher.tt.store(pos, ply, raw_eval, m, probcut_value, probcut_depth, false, @@ -878,6 +884,9 @@ Value Worker::search( // Do move ss->cont_hist_entry = &m_td.history.get_cont_hist_entry(pos, m); + ss->move = m; + ss->moved_piece = pos.piece_at(m.from()); + ss->cont_corr_entry = &m_td.history.get_cont_corr_entry(pos, m); Position pos_after = pos.move(m, m_td.push_psqt_state(), &m_searcher.tt); moves_played++; @@ -986,6 +995,9 @@ Value Worker::search( repetition_info.pop(); m_td.pop_psqt_state(); ss->cont_hist_entry = nullptr; + ss->move = Move::none(); + ss->moved_piece = PieceType::None; + ss->cont_corr_entry = nullptr; if (m_stopped) { return 0; @@ -1099,7 +1111,8 @@ Value Worker::search( && !(best_move != Move::none() && (best_move.is_capture() || best_move.is_promotion())) && !((bound == Bound::Lower && best_value <= ss->static_eval) || (bound == Bound::Upper && best_value >= ss->static_eval))) { - m_td.history.update_correction_history(pos, depth, best_value - ss->static_eval); + m_td.history.update_correction_history(pos, depth, best_value - ss->static_eval, ply, + ss); } } @@ -1166,7 +1179,7 @@ Value Worker::quiesce(const Position& pos, Stack* ss, Value alpha, Value beta, i Value raw_eval = -VALUE_INF; Value static_eval = -VALUE_INF; if (!is_in_check) { - correction = m_td.history.get_correction(pos); + correction = m_td.history.get_correction(pos, ply, ss); raw_eval = tt_data && !is_decisive_score(tt_data->eval) ? tt_data->eval : evaluate(pos); static_eval = adj_shuffle(pos, raw_eval) + correction; @@ -1204,6 +1217,9 @@ Value Worker::quiesce(const Position& pos, Stack* ss, Value alpha, Value beta, i // Do move ss->cont_hist_entry = &m_td.history.get_cont_hist_entry(pos, m); + ss->move = m; + ss->moved_piece = pos.piece_at(m.from()); + ss->cont_corr_entry = &m_td.history.get_cont_corr_entry(pos, m); Position pos_after = pos.move(m, m_td.push_psqt_state(), &m_searcher.tt); moves_searched++; @@ -1220,6 +1236,9 @@ Value Worker::quiesce(const Position& pos, Stack* ss, Value alpha, Value beta, i repetition_info.pop(); m_td.pop_psqt_state(); ss->cont_hist_entry = nullptr; + ss->move = Move::none(); + ss->moved_piece = PieceType::None; + ss->cont_corr_entry = nullptr; if (m_stopped) { return 0; diff --git a/src/search.hpp b/src/search.hpp index e86d7566..01cc9c8f 100644 --- a/src/search.hpp +++ b/src/search.hpp @@ -46,6 +46,9 @@ struct Stack { Move killer = Move::none(); Move excluded_move; ContHistEntry* cont_hist_entry = nullptr; + Move move = Move::none(); + PieceType moved_piece = PieceType::None; + ContCorrEntry* cont_corr_entry = nullptr; i32 fail_high_count = 0; PV pv; };