-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Avoid unnecessarily initializing TTData with 0's. #5766
Conversation
clang-format 18 needs to be run on this PR. (execution 12732451394 / attempt 1) |
No functional change bench: 999324
I think this exposes that we are making use of ttData somewhere in search without checking that ttHit is true. I suspect this is why the PR checks are failing. Issue #5503 |
|
Okay so for the sanitizer warning I've opened a bug report https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118436. The gcc behaviour is weird.. though I mean this is such a micro optimization patch and the only thing it highlights is maybe something wrong in search but i'd really prefer stuff be properly initialized unless it's causing a real measurable performance degradation |
i opened a bug report for the gcc initialization case (i hope that was fine with you) https://gcc.gnu.org/bugzilla/show_bug.cgi?id=118440, lets see what they say.. update: duplicate of https://gcc.gnu.org/bugzilla/show_bug.cgi?id=61810 |
to fix your branch you'd need to add those... diff --git a/src/search.cpp b/src/search.cpp
index e8a9f0b9..49805c32 100644
--- a/src/search.cpp
+++ b/src/search.cpp
@@ -853,7 +853,7 @@ Value Search::Worker::search(
// If we have a good enough capture (or queen promotion) and a reduced search
// returns a value much above beta, we can (almost) safely prune the previous move.
probCutBeta = beta + 187 - 56 * improving;
- if (!PvNode && depth > 3
+ if (!PvNode && depth > 3 && ttHit
&& !is_decisive(beta)
// If value from transposition table is lower than probCutBeta, don't attempt
// probCut there and in further interactions with transposition table cutoff
@@ -922,8 +922,9 @@ moves_loop: // When in check, search starts here
// Step 12. A small Probcut idea (~4 Elo)
probCutBeta = beta + 417;
- if (ttHit && (ttData.bound & BOUND_LOWER) && ttData.depth >= depth - 4 && ttData.value >= probCutBeta
- && !is_decisive(beta) && is_valid(ttData.value) && !is_decisive(ttData.value))
+ if (ttHit && (ttData.bound & BOUND_LOWER) && ttData.depth >= depth - 4
+ && ttData.value >= probCutBeta && !is_decisive(beta) && is_valid(ttData.value)
+ && !is_decisive(ttData.value))
return probCutBeta;
const PieceToHistory* contHist[] = {(ss - 1)->continuationHistory,
@@ -1150,7 +1151,8 @@ moves_loop: // When in check, search starts here
// Decrease reduction if position is or has been on the PV (~7 Elo)
if (ss->ttPv)
- r -= 1024 + (ttData.value > alpha) * 1024 + (ttData.depth >= depth) * 1024;
+ r -= 1024 + (ttHit && ttData.value > alpha) * 1024
+ + (ttHit && ttData.depth >= depth) * 1024;
// Decrease reduction for PvNodes (~0 Elo on STC, ~2 Elo on LTC)
if (PvNode)
@@ -1164,7 +1166,7 @@ moves_loop: // When in check, search starts here
// Increase reduction for cut nodes (~4 Elo)
if (cutNode)
- r += 2518 - (ttData.depth >= depth && ss->ttPv) * 991;
+ r += 2518 - (ttHit && ttData.depth >= depth && ss->ttPv) * 991;
// Increase reduction if ttMove is a capture but the current move is not a capture (~3 Elo)
if (ttCapture && !capture)
@@ -1175,7 +1177,7 @@ moves_loop: // When in check, search starts here
r += 938 + allNode * 960;
// For first picked move (ttMove) reduce reduction (~3 Elo)
- else if (move == ttData.move)
+ else if (ttHit && move == ttData.move)
r -= 1879;
if (capture)
@@ -1227,7 +1229,7 @@ moves_loop: // When in check, search starts here
else if (!PvNode || moveCount > 1)
{
// Increase reduction if ttMove is not present (~6 Elo)
- if (!ttData.move)
+ if (ttHit && !ttData.move)
r += 2037;
// Note that if expected reduction is high, we reduce search depth by 1 here (~9 Elo)
@@ -1527,7 +1529,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta)
pvHit = ttHit && ttData.is_pv;
// At non-PV nodes we check for an early TT cutoff
- if (!PvNode && ttData.depth >= DEPTH_QS
+ if (!PvNode && ttHit && ttData.depth >= DEPTH_QS
&& is_valid(ttData.value) // Can happen when !ttHit or when access race in probe()
&& (ttData.bound & (ttData.value >= beta ? BOUND_LOWER : BOUND_UPPER)))
return ttData.value; this patch makes the code generally too prone errors, let there be default initialization and maybe change it to good default, i.e. VALUE_NONE |
See official-stockfish#5766 No functional change bench: 1379150
@Disservin
|
A TT entry doesn't have to have a TT move, so the intended condition is probably |
The zeroing of the struct is normal under cpp rules afaik. The only thing gcc doesn’t do right is, that it apparently keeps this zeroing even with a user defined constructor. Yeah id much rather have that patch pass than others, though I’m not sure if that depth entry offset makes sense, 0 is probably less weird. Checking for tthit at every place we use tt data slows it down more than zeroing/initialing it to sane defaults I imagine. I didn’t quite check my suggested changes in great detail just made sure valgrind was happy locally. (Use clang to compile and then run valgrind) having to use tthit everywhere is too brittle I fear |
Agree. I used DEPTH_ENTRY_OFFSET instead of 0 to make sure it's lower than DEPTH_UNSEARCHED. Do you want me to stop the test and resubmit with 0? |
Actually I forgot it already passed https://tests.stockfishchess.org/tests/view/6757757686d5ee47d9541de9 when I was trying to fix #5503 Is that acceptable? |
0 might conflict with the value of DEPTH_QS, maybe just use DEPTH_UNSEARCHED for this? |
makes more sense from a naming standpoint, I think the depth value isn't really used anywhere relevant so -3 and -2 should have no diff? |
but yeah that patch @mstembera generally looks fine |
See official-stockfish#5766 No functional change bench: 1379150
In practice with the current code base there is no diff between -3 or -2. However, DEPTH_UNSEARCHED is still a value that gets written to the TT by search and is considered a valid depth. Line 753 in c085670
|
https://tests.stockfishchess.org/tests/view/6757757686d5ee47d9541de9 LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 151200 W: 39396 L: 39306 D: 72498 Ptnml(0-2): 445, 16404, 41781, 16556, 414 Discussed in more detail here official-stockfish#5766 closes official-stockfish#5773 No functional change
The compiler generated default constructor is initializing TTData with 0's when we invoke it here
Stockfish/src/tt.cpp
Line 241 in c76c179
An empty default constructor avoids this as shown here https://godbolt.org/z/a8q8o3EEz
(For some reason gcc initializes to 0 even with an empty constructor which seems like a gcc bug?)
No functional change
bench: 999324