Fix MultiArray::at(); use operator[] on hot paths

Fix MultiArray::at() which was marked noexcept despite delegating to
std::array::at() that throws on out-of-range. Per review feedback, at() now
keeps standard bounds-checking semantics (only noexcept removed), and
operator[] gains an assert for debug-mode safety.

All eight correction history lookups in search.cpp (correction_value and
update_correction_history) are switched from .at(us) to [us].

Passed STC:
https://tests.stockfishchess.org/tests/view/69de7a735c67bee7d241ff92
LLR: 2.96 (-2.94,2.94) <-1.75,0.25>
Total: 77536 W: 20031 L: 19860 D: 37645
Ptnml(0-2): 221, 8411, 21338, 8572, 226

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

No functional change
This commit is contained in:
Maxim Masiutin
2026-04-19 07:19:23 +02:00
committed by Joost VandeVondele
parent cc4637b52b
commit 40ac93b8f8
2 changed files with 18 additions and 12 deletions
+10 -4
View File
@@ -266,11 +266,17 @@ class MultiArray {
using reverse_iterator = typename ArrayType::reverse_iterator;
using const_reverse_iterator = typename ArrayType::const_reverse_iterator;
constexpr auto& at(size_type index) noexcept { return data_.at(index); }
constexpr const auto& at(size_type index) const noexcept { return data_.at(index); }
constexpr auto& at(size_type index) { return data_.at(index); }
constexpr const auto& at(size_type index) const { return data_.at(index); }
constexpr auto& operator[](size_type index) noexcept { return data_[index]; }
constexpr const auto& operator[](size_type index) const noexcept { return data_[index]; }
constexpr auto& operator[](size_type index) noexcept {
assert(index < Size);
return data_[index];
}
constexpr const auto& operator[](size_type index) const noexcept {
assert(index < Size);
return data_[index];
}
constexpr auto& front() noexcept { return data_.front(); }
constexpr const auto& front() const noexcept { return data_.front(); }
+8 -8
View File
@@ -85,10 +85,10 @@ int correction_value(const Worker& w, const Position& pos, const Stack* const ss
const Color us = pos.side_to_move();
const auto m = (ss - 1)->currentMove;
const auto& shared = w.sharedHistory;
const int pcv = shared.pawn_correction_entry(pos).at(us).pawn;
const int micv = shared.minor_piece_correction_entry(pos).at(us).minor;
const int wnpcv = shared.nonpawn_correction_entry<WHITE>(pos).at(us).nonPawnWhite;
const int bnpcv = shared.nonpawn_correction_entry<BLACK>(pos).at(us).nonPawnBlack;
const int pcv = shared.pawn_correction_entry(pos)[us].pawn;
const int micv = shared.minor_piece_correction_entry(pos)[us].minor;
const int wnpcv = shared.nonpawn_correction_entry<WHITE>(pos)[us].nonPawnWhite;
const int bnpcv = shared.nonpawn_correction_entry<BLACK>(pos)[us].nonPawnBlack;
const int cntcv =
m.is_ok() ? (*(ss - 2)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()]
+ (*(ss - 4)->continuationCorrectionHistory)[pos.piece_on(m.to_sq())][m.to_sq()]
@@ -113,10 +113,10 @@ void update_correction_history(const Position& pos,
constexpr int nonPawnWeight = 187;
auto& shared = workerThread.sharedHistory;
shared.pawn_correction_entry(pos).at(us).pawn << bonus;
shared.minor_piece_correction_entry(pos).at(us).minor << bonus * 153 / 128;
shared.nonpawn_correction_entry<WHITE>(pos).at(us).nonPawnWhite << bonus * nonPawnWeight / 128;
shared.nonpawn_correction_entry<BLACK>(pos).at(us).nonPawnBlack << bonus * nonPawnWeight / 128;
shared.pawn_correction_entry(pos)[us].pawn << bonus;
shared.minor_piece_correction_entry(pos)[us].minor << bonus * 153 / 128;
shared.nonpawn_correction_entry<WHITE>(pos)[us].nonPawnWhite << bonus * nonPawnWeight / 128;
shared.nonpawn_correction_entry<BLACK>(pos)[us].nonPawnBlack << bonus * nonPawnWeight / 128;
if (m.is_ok())
{