From 6db47ed71aac3b1667dd68a08c39bfde0fe0a2ab Mon Sep 17 00:00:00 2001 From: Viren6 <94880762+Viren6@users.noreply.github.com> Date: Sun, 19 May 2024 02:58:01 +0100 Subject: [PATCH 01/13] Addition of new scaling comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This patch is intended to prevent patches like 9b90cd8 and the subsequent reversion e3c9ed7 from happening again. Scaling behaviour of the reduction adjustments in the non-linear scaling section have been proven to >8 sigma: STC: https://tests.stockfishchess.org/tests/view/6647b19f6dcff0d1d6b05d52 Elo: 4.28 ± 0.8 (95%) LOS: 100.0% Total: 200000 W: 52555 L: 50094 D: 97351 Ptnml(0-2): 573, 22628, 51248, 24867, 684 nElo: 8.35 ± 1.5 (95%) PairsRatio: 1.10 VLTC: https://tests.stockfishchess.org/tests/view/6647b1b06dcff0d1d6b05d54 Elo: -1.48 ± 1.0 (95%) LOS: 0.2% Total: 100000 W: 25009 L: 25436 D: 49555 Ptnml(0-2): 11, 10716, 28971, 10293, 9 nElo: -3.23 ± 2.2 (95%) PairsRatio: 0.96 The else if condition is moved to the non scaling section based on: https://tests.stockfishchess.org/tests/view/664567a193ce6da3e93b3232 (It has no proven scaling) General comment improvements and removal of a redundant margin condition have also been included. closes https://github.com/official-stockfish/Stockfish/pull/5266 No functional change --- src/search.cpp | 32 ++++++++++++++++++++------------ 1 file changed, 20 insertions(+), 12 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 87cfdbc2b..081418186 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -840,7 +840,8 @@ Value Search::Worker::search( if (depth <= 0) return qsearch < PvNode ? PV : NonPV > (pos, ss, alpha, beta); - // For cutNodes without a ttMove, we decrease depth by 2 if depth is high enough. + // For cutNodes, if depth is high enough, decrease depth by 2 if there is no ttMove, or + // by 1 if there is a ttMove with an upper bound. if (cutNode && depth >= 8 && (!ttMove || tte->bound() == BOUND_UPPER)) depth -= 1 + !ttMove; @@ -1042,11 +1043,14 @@ moves_loop: // When in check, search starts here // then that move is singular and should be extended. To verify this we do // a reduced search on the position excluding the ttMove and if the result // is lower than ttValue minus a margin, then we will extend the ttMove. + // Recursive singular search is avoided. // Note: the depth margin and singularBeta margin are known for having non-linear // scaling. Their values are optimized to time controls of 180+1.8 and longer // so changing them requires tests at these types of time controls. - // Recursive singular search is avoided. + // Generally, higher singularBeta (i.e closer to ttValue) and lower extension + // margins scale well. + if (!rootNode && move == ttMove && !excludedMove && depth >= 4 - (thisThread->completedDepth > 35) + ss->ttPv && std::abs(ttValue) < VALUE_TB_WIN_IN_MAX_PLY && (tte->bound() & BOUND_LOWER) @@ -1063,9 +1067,8 @@ moves_loop: // When in check, search starts here if (value < singularBeta) { int doubleMargin = 298 * PvNode - 209 * !ttCapture; - int tripleMargin = - 117 + 252 * PvNode - 270 * !ttCapture + 111 * (ss->ttPv || !ttCapture); - int quadMargin = 471 + 343 * PvNode - 281 * !ttCapture + 217 * ss->ttPv; + int tripleMargin = 117 + 252 * PvNode - 270 * !ttCapture + 111 * ss->ttPv; + int quadMargin = 471 + 343 * PvNode - 281 * !ttCapture + 217 * ss->ttPv; extension = 1 + (value < singularBeta - doubleMargin) + (value < singularBeta - tripleMargin) @@ -1127,25 +1130,30 @@ moves_loop: // When in check, search starts here thisThread->nodes.fetch_add(1, std::memory_order_relaxed); pos.do_move(move, st, givesCheck); + // These reduction adjustments have proven non-linear scaling. + // They are optimized to time controls of 180 + 1.8 and longer so + // changing them or adding conditions that are similar + // requires tests at these types of time controls. + // Decrease reduction if position is or has been on the PV (~7 Elo) if (ss->ttPv) r -= 1 + (ttValue > alpha) + (tte->depth() >= depth); - else if (cutNode && move != ttMove && move != ss->killers[0]) - r++; + // Decrease reduction for PvNodes (~0 Elo on STC, ~2 Elo on LTC) + if (PvNode) + r--; + + // These reduction adjustments have no proven non-linear scaling. // Increase reduction for cut nodes (~4 Elo) if (cutNode) - r += 2 - (tte->depth() >= depth && ss->ttPv); + r += 2 - (tte->depth() >= depth && ss->ttPv) + + (!ss->ttPv && move != ttMove && move != ss->killers[0]); // Increase reduction if ttMove is a capture (~3 Elo) if (ttCapture) r++; - // Decrease reduction for PvNodes (~0 Elo on STC, ~2 Elo on LTC) - if (PvNode) - r--; - // Increase reduction if next ply has a lot of fail high (~5 Elo) if ((ss + 1)->cutoffCnt > 3) r++; From 1dcffa621065f58982feb462671d79404e51e088 Mon Sep 17 00:00:00 2001 From: Linmiao Xu Date: Tue, 21 May 2024 22:50:44 -0400 Subject: [PATCH 02/13] Comment about re-evaluating positions While the smallNet bool is no longer used as of now, setting it to false upon re-evaluation represents the correct eval state. closes https://github.com/official-stockfish/Stockfish/pull/5279 No functional change --- src/evaluate.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index ca09aaf9e..4c4497748 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -66,6 +66,7 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, Value nnue = smallNet ? networks.small.evaluate(pos, &caches.small, true, &nnueComplexity) : networks.big.evaluate(pos, &caches.big, true, &nnueComplexity); + // Re-evaluate the position when higher eval accuracy is worth the time spent if (smallNet && nnue * simpleEval < 0) { nnue = networks.big.evaluate(pos, &caches.big, true, &nnueComplexity); From c39b98b9e356f6d01d323c6e6d5badd50e31c980 Mon Sep 17 00:00:00 2001 From: Shawn Xu Date: Tue, 21 May 2024 11:54:53 -0700 Subject: [PATCH 03/13] Simplify Away History Updates in Multicut Passed Non-regression STC: LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 44896 W: 11600 L: 11388 D: 21908 Ptnml(0-2): 140, 5230, 11532, 5370, 176 https://tests.stockfishchess.org/tests/view/664cee31830eb9f886616a80 Passed Non-regression LTC: LLR: 2.96 (-2.94,2.94) <-1.75,0.25> Total: 56832 W: 14421 L: 14234 D: 28177 Ptnml(0-2): 37, 6251, 15643, 6458, 27 https://tests.stockfishchess.org/tests/view/664cfd4e830eb9f886616aa6 closes https://github.com/official-stockfish/Stockfish/pull/5281 Bench: 1119412 --- src/search.cpp | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 081418186..a98468ec6 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1083,12 +1083,7 @@ moves_loop: // When in check, search starts here // we assume this expected cut-node is not singular (multiple moves fail high), // and we can prune the whole subtree by returning a softbound. else if (singularBeta >= beta) - { - if (!ttCapture) - update_quiet_histories(pos, ss, *this, ttMove, -stat_malus(depth)); - return singularBeta; - } // Negative extensions // If other moves failed high over (ttValue - margin) without the ttMove on a reduced search, From c6a1e7fd4232ec151206fab16cb7daa23bfd7137 Mon Sep 17 00:00:00 2001 From: cj5716 <125858804+cj5716@users.noreply.github.com> Date: Sun, 19 May 2024 13:15:42 +0800 Subject: [PATCH 04/13] Optimise pairwise multiplication This speedup was first inspired by a comment by @AndyGrant on my recent PR "If mullo_epi16 would preserve the signedness, then this could be used to remove 50% of the max operations during the halfkp-pairwise mat-mul relu deal." That got me thinking, because although mullo_epi16 did not preserve the signedness, mulhi_epi16 did, and so we could shift left and then use mulhi_epi16, instead of shifting right after the mullo. However, due to some issues with shifting into the sign bit, the FT weights and biases had to be multiplied by 2 for the optimisation to work. Speedup on "Arch=x86-64-bmi2 COMP=clang", courtesy of @Torom Result of 50 runs base (...es/stockfish) = 962946 +/- 1202 test (...ise-max-less) = 979696 +/- 1084 diff = +16750 +/- 1794 speedup = +0.0174 P(speedup > 0) = 1.0000 CPU: 4 x Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz Hyperthreading: on Also a speedup on "COMP=gcc", courtesy of Torom once again Result of 50 runs base (...tockfish_gcc) = 966033 +/- 1574 test (...max-less_gcc) = 983319 +/- 1513 diff = +17286 +/- 2515 speedup = +0.0179 P(speedup > 0) = 1.0000 CPU: 4 x Intel(R) Core(TM) i7-6700K CPU @ 4.00GHz Hyperthreading: on Passed STC: LLR: 2.96 (-2.94,2.94) <0.00,2.00> Total: 67712 W: 17715 L: 17358 D: 32639 Ptnml(0-2): 225, 7472, 18140, 7759, 260 https://tests.stockfishchess.org/tests/view/664c1d75830eb9f886616906 closes https://github.com/official-stockfish/Stockfish/pull/5282 No functional change --- src/nnue/nnue_feature_transformer.h | 80 +++++++++++++++++++---------- 1 file changed, 54 insertions(+), 26 deletions(-) diff --git a/src/nnue/nnue_feature_transformer.h b/src/nnue/nnue_feature_transformer.h index 7b7aada31..483b84a87 100644 --- a/src/nnue/nnue_feature_transformer.h +++ b/src/nnue/nnue_feature_transformer.h @@ -55,14 +55,14 @@ using psqt_vec_t = __m256i; #define vec_store(a, b) _mm512_store_si512(a, b) #define vec_add_16(a, b) _mm512_add_epi16(a, b) #define vec_sub_16(a, b) _mm512_sub_epi16(a, b) - #define vec_mul_16(a, b) _mm512_mullo_epi16(a, b) + #define vec_mulhi_16(a, b) _mm512_mulhi_epi16(a, b) #define vec_zero() _mm512_setzero_epi32() #define vec_set_16(a) _mm512_set1_epi16(a) #define vec_max_16(a, b) _mm512_max_epi16(a, b) #define vec_min_16(a, b) _mm512_min_epi16(a, b) + #define vec_slli_16(a, b) _mm512_slli_epi16(a, b) // Inverse permuted at load time - #define vec_msb_pack_16(a, b) \ - _mm512_packs_epi16(_mm512_srli_epi16(a, 7), _mm512_srli_epi16(b, 7)) + #define vec_packus_16(a, b) _mm512_packus_epi16(a, b) #define vec_load_psqt(a) _mm256_load_si256(a) #define vec_store_psqt(a, b) _mm256_store_si256(a, b) #define vec_add_psqt_32(a, b) _mm256_add_epi32(a, b) @@ -78,14 +78,14 @@ using psqt_vec_t = __m256i; #define vec_store(a, b) _mm256_store_si256(a, b) #define vec_add_16(a, b) _mm256_add_epi16(a, b) #define vec_sub_16(a, b) _mm256_sub_epi16(a, b) - #define vec_mul_16(a, b) _mm256_mullo_epi16(a, b) + #define vec_mulhi_16(a, b) _mm256_mulhi_epi16(a, b) #define vec_zero() _mm256_setzero_si256() #define vec_set_16(a) _mm256_set1_epi16(a) #define vec_max_16(a, b) _mm256_max_epi16(a, b) #define vec_min_16(a, b) _mm256_min_epi16(a, b) + #define vec_slli_16(a, b) _mm256_slli_epi16(a, b) // Inverse permuted at load time - #define vec_msb_pack_16(a, b) \ - _mm256_packs_epi16(_mm256_srli_epi16(a, 7), _mm256_srli_epi16(b, 7)) + #define vec_packus_16(a, b) _mm256_packus_epi16(a, b) #define vec_load_psqt(a) _mm256_load_si256(a) #define vec_store_psqt(a, b) _mm256_store_si256(a, b) #define vec_add_psqt_32(a, b) _mm256_add_epi32(a, b) @@ -101,12 +101,13 @@ using psqt_vec_t = __m128i; #define vec_store(a, b) *(a) = (b) #define vec_add_16(a, b) _mm_add_epi16(a, b) #define vec_sub_16(a, b) _mm_sub_epi16(a, b) - #define vec_mul_16(a, b) _mm_mullo_epi16(a, b) + #define vec_mulhi_16(a, b) _mm_mulhi_epi16(a, b) #define vec_zero() _mm_setzero_si128() #define vec_set_16(a) _mm_set1_epi16(a) #define vec_max_16(a, b) _mm_max_epi16(a, b) #define vec_min_16(a, b) _mm_min_epi16(a, b) - #define vec_msb_pack_16(a, b) _mm_packs_epi16(_mm_srli_epi16(a, 7), _mm_srli_epi16(b, 7)) + #define vec_slli_16(a, b) _mm_slli_epi16(a, b) + #define vec_packus_16(a, b) _mm_packus_epi16(a, b) #define vec_load_psqt(a) (*(a)) #define vec_store_psqt(a, b) *(a) = (b) #define vec_add_psqt_32(a, b) _mm_add_epi32(a, b) @@ -122,18 +123,14 @@ using psqt_vec_t = int32x4_t; #define vec_store(a, b) *(a) = (b) #define vec_add_16(a, b) vaddq_s16(a, b) #define vec_sub_16(a, b) vsubq_s16(a, b) - #define vec_mul_16(a, b) vmulq_s16(a, b) + #define vec_mulhi_16(a, b) vqdmulhq_s16(a, b) #define vec_zero() \ vec_t { 0 } #define vec_set_16(a) vdupq_n_s16(a) #define vec_max_16(a, b) vmaxq_s16(a, b) #define vec_min_16(a, b) vminq_s16(a, b) -inline vec_t vec_msb_pack_16(vec_t a, vec_t b) { - const int8x8_t shifta = vshrn_n_s16(a, 7); - const int8x8_t shiftb = vshrn_n_s16(b, 7); - const int8x16_t compacted = vcombine_s8(shifta, shiftb); - return *reinterpret_cast(&compacted); -} + #define vec_slli_16(a, b) vshlq_s16(a, vec_set_16(b)) + #define vec_packus_16(a, b) reinterpret_cast(vcombine_u8(vqmovun_s16(a), vqmovun_s16(b))) #define vec_load_psqt(a) (*(a)) #define vec_store_psqt(a, b) *(a) = (b) #define vec_add_psqt_32(a, b) vaddq_s32(a, b) @@ -281,6 +278,19 @@ class FeatureTransformer { #endif } + inline void scale_weights(bool read) const { + for (IndexType j = 0; j < InputDimensions; ++j) + { + WeightType* w = const_cast(&weights[j * HalfDimensions]); + for (IndexType i = 0; i < HalfDimensions; ++i) + w[i] = read ? w[i] * 2 : w[i] / 2; + } + + BiasType* b = const_cast(biases); + for (IndexType i = 0; i < HalfDimensions; ++i) + b[i] = read ? b[i] * 2 : b[i] / 2; + } + // Read network parameters bool read_parameters(std::istream& stream) { @@ -289,6 +299,7 @@ class FeatureTransformer { read_leb_128(stream, psqtWeights, PSQTBuckets * InputDimensions); permute_weights(inverse_order_packs); + scale_weights(true); return !stream.fail(); } @@ -296,12 +307,14 @@ class FeatureTransformer { bool write_parameters(std::ostream& stream) const { permute_weights(order_packs); + scale_weights(false); write_leb_128(stream, biases, HalfDimensions); write_leb_128(stream, weights, HalfDimensions * InputDimensions); write_leb_128(stream, psqtWeights, PSQTBuckets * InputDimensions); permute_weights(inverse_order_packs); + scale_weights(true); return !stream.fail(); } @@ -332,7 +345,7 @@ class FeatureTransformer { constexpr IndexType NumOutputChunks = HalfDimensions / 2 / OutputChunkSize; const vec_t Zero = vec_zero(); - const vec_t One = vec_set_16(127); + const vec_t One = vec_set_16(127 * 2); const vec_t* in0 = reinterpret_cast(&(accumulation[perspectives[p]][0])); const vec_t* in1 = @@ -341,15 +354,30 @@ class FeatureTransformer { for (IndexType j = 0; j < NumOutputChunks; ++j) { - const vec_t sum0a = vec_max_16(vec_min_16(in0[j * 2 + 0], One), Zero); - const vec_t sum0b = vec_max_16(vec_min_16(in0[j * 2 + 1], One), Zero); - const vec_t sum1a = vec_max_16(vec_min_16(in1[j * 2 + 0], One), Zero); - const vec_t sum1b = vec_max_16(vec_min_16(in1[j * 2 + 1], One), Zero); + // What we want to do is multiply inputs in a pairwise manner (after clipping), and then shift right by 9. + // Instead, we shift left by 7, and use mulhi, stripping the bottom 16 bits, effectively shifting right by 16, + // resulting in a net shift of 9 bits. We use mulhi because it maintains the sign of the multiplication (unlike mullo), + // allowing us to make use of packus to clip 2 of the inputs, resulting in a save of 2 "vec_max_16" calls. + // A special case is when we use NEON, where we shift left by 6 instead, because the instruction "vqdmulhq_s16" + // also doubles the return value after the multiplication, adding an extra shift to the left by 1, so we + // compensate by shifting less before the multiplication. - const vec_t pa = vec_mul_16(sum0a, sum1a); - const vec_t pb = vec_mul_16(sum0b, sum1b); + #if defined(USE_SSE2) + constexpr int shift = 7; + #else + constexpr int shift = 6; + #endif + const vec_t sum0a = + vec_slli_16(vec_max_16(vec_min_16(in0[j * 2 + 0], One), Zero), shift); + const vec_t sum0b = + vec_slli_16(vec_max_16(vec_min_16(in0[j * 2 + 1], One), Zero), shift); + const vec_t sum1a = vec_min_16(in1[j * 2 + 0], One); + const vec_t sum1b = vec_min_16(in1[j * 2 + 1], One); - out[j] = vec_msb_pack_16(pa, pb); + const vec_t pa = vec_mulhi_16(sum0a, sum1a); + const vec_t pb = vec_mulhi_16(sum0b, sum1b); + + out[j] = vec_packus_16(pa, pb); } #else @@ -359,9 +387,9 @@ class FeatureTransformer { BiasType sum0 = accumulation[static_cast(perspectives[p])][j + 0]; BiasType sum1 = accumulation[static_cast(perspectives[p])][j + HalfDimensions / 2]; - sum0 = std::clamp(sum0, 0, 127); - sum1 = std::clamp(sum1, 0, 127); - output[offset + j] = static_cast(unsigned(sum0 * sum1) / 128); + sum0 = std::clamp(sum0, 0, 127 * 2); + sum1 = std::clamp(sum1, 0, 127 * 2); + output[offset + j] = static_cast(unsigned(sum0 * sum1) / 512); } #endif From 72a345873d9cf24542dc73cd5a28eba7d23b0d2b Mon Sep 17 00:00:00 2001 From: Muzhen Gaming <61100393+XInTheDark@users.noreply.github.com> Date: Wed, 22 May 2024 09:09:04 +0800 Subject: [PATCH 05/13] Revert "Reduce When TTValue is Above Alpha" The patch regressed significantly at longer time controls. In particular, the `depth--` behavior was predicted to scale badly based on data from other variations of the patch. Passed VVLTC 1st sprt: https://tests.stockfishchess.org/tests/view/664d45cf830eb9f886616c7d LLR: 2.95 (-2.94,2.94) <0.00,2.00> Total: 51292 W: 13242 L: 12954 D: 25096 Ptnml(0-2): 5, 4724, 15896, 5020, 1 Passed VVLTC 2nd sprt: https://tests.stockfishchess.org/tests/view/664e641a928b1fb18de4e385 LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 41884 W: 10933 L: 10634 D: 20317 Ptnml(0-2): 1, 3759, 13125, 4054, 3 closes https://github.com/official-stockfish/Stockfish/pull/5283 Bench: 1503815 --- src/search.cpp | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index a98468ec6..477667306 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -833,12 +833,9 @@ Value Search::Worker::search( if (PvNode && !ttMove) depth -= 3; - if (!PvNode && ss->ttHit && (tte->bound() & BOUND_UPPER) && ttValue > alpha + 5 * depth) - depth--; - // Use qsearch if depth <= 0. if (depth <= 0) - return qsearch < PvNode ? PV : NonPV > (pos, ss, alpha, beta); + return qsearch(pos, ss, alpha, beta); // For cutNodes, if depth is high enough, decrease depth by 2 if there is no ttMove, or // by 1 if there is a ttMove with an upper bound. From 365aa85dcea3adee21b5e01a7941b4b18fdc8194 Mon Sep 17 00:00:00 2001 From: Linmiao Xu Date: Tue, 21 May 2024 16:24:49 -0400 Subject: [PATCH 06/13] Remove material imbalance param when adjusting optimism Passed non-regression STC: https://tests.stockfishchess.org/tests/view/664d033d830eb9f886616aff LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 102144 W: 26283 L: 26135 D: 49726 Ptnml(0-2): 292, 12201, 25991, 12243, 345 Passed non-regression LTC: https://tests.stockfishchess.org/tests/view/664d5c00830eb9f886616cb3 LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 250032 W: 63022 L: 63036 D: 123974 Ptnml(0-2): 103, 27941, 68970, 27871, 131 closes https://github.com/official-stockfish/Stockfish/pull/5284 Bench: 1330940 --- src/evaluate.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 4c4497748..7ca470af5 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -73,8 +73,8 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, smallNet = false; } - // Blend optimism and eval with nnue complexity and material imbalance - optimism += optimism * (nnueComplexity + std::abs(simpleEval - nnue)) / 620; + // Blend optimism and eval with nnue complexity + optimism += optimism * nnueComplexity / 512; nnue -= nnue * (nnueComplexity * 5 / 3) / 32082; v = (nnue From 61acbfc7d310ed6044ba4fc5ef91a6c382d1c9a6 Mon Sep 17 00:00:00 2001 From: Muzhen Gaming <61100393+XInTheDark@users.noreply.github.com> Date: Thu, 23 May 2024 08:28:46 +0800 Subject: [PATCH 07/13] VVLTC search tune Parameters were tuned in 2 stages: 1. 127k games at VVLTC: https://tests.stockfishchess.org/tests/view/6649f8dfb8fa20e74c39f52a. 2. 106k games at VVLTC: https://tests.stockfishchess.org/tests/view/664bfb77830eb9f886615a9d. Passed VVLTC 1st sprt: https://tests.stockfishchess.org/tests/view/664e8dd9928b1fb18de4e410 LLR: 2.94 (-2.94,2.94) <0.00,2.00> Total: 20466 W: 5340 L: 5093 D: 10033 Ptnml(0-2): 0, 1796, 6397, 2037, 3 Passed VVLTC 2nd sprt: https://tests.stockfishchess.org/tests/view/664eb4aa928b1fb18de4e47d LLR: 2.95 (-2.94,2.94) <0.50,2.50> Total: 15854 W: 4186 L: 3934 D: 7734 Ptnml(0-2): 1, 1367, 4938, 1621, 0 closes https://github.com/official-stockfish/Stockfish/pull/5286 Bench: 1558110 --- src/search.cpp | 88 +++++++++++++++++++++++++------------------------- 1 file changed, 44 insertions(+), 44 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 477667306..563a5710f 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -60,9 +60,9 @@ static constexpr double EvalLevel[10] = {0.981, 0.956, 0.895, 0.949, 0.913, // Futility margin Value futility_margin(Depth d, bool noTtCutNode, bool improving, bool oppWorsening) { - Value futilityMult = 127 - 48 * noTtCutNode; - Value improvingDeduction = 65 * improving * futilityMult / 32; - Value worseningDeduction = 334 * oppWorsening * futilityMult / 1024; + Value futilityMult = 129 - 43 * noTtCutNode; + Value improvingDeduction = 56 * improving * futilityMult / 32; + Value worseningDeduction = 336 * oppWorsening * futilityMult / 1024; return futilityMult * d - improvingDeduction - worseningDeduction; } @@ -74,15 +74,15 @@ constexpr int futility_move_count(bool improving, Depth depth) { // Add correctionHistory value to raw staticEval and guarantee evaluation does not hit the tablebase range Value to_corrected_static_eval(Value v, const Worker& w, const Position& pos) { auto cv = w.correctionHistory[pos.side_to_move()][pawn_structure_index(pos)]; - v += cv * std::abs(cv) / 6047; + v += cv * std::abs(cv) / 5435; return std::clamp(v, VALUE_TB_LOSS_IN_MAX_PLY + 1, VALUE_TB_WIN_IN_MAX_PLY - 1); } // History and stats update bonus, based on depth -int stat_bonus(Depth d) { return std::clamp(187 * d - 288, 17, 1548); } +int stat_bonus(Depth d) { return std::clamp(205 * d - 283, 18, 1544); } // History and stats update malus, based on depth -int stat_malus(Depth d) { return (d < 4 ? 630 * d - 281 : 1741); } +int stat_malus(Depth d) { return (d < 4 ? 767 * d - 275 : 1911); } // Add a small random component to draw evaluations to avoid 3-fold blindness Value value_draw(size_t nodes) { return VALUE_DRAW - 1 + Value(nodes & 0x2); } @@ -312,12 +312,12 @@ void Search::Worker::iterative_deepening() { // Reset aspiration window starting size Value avg = rootMoves[pvIdx].averageScore; - delta = 10 + avg * avg / 9828; + delta = 9 + avg * avg / 10502; alpha = std::max(avg - delta, -VALUE_INFINITE); beta = std::min(avg + delta, VALUE_INFINITE); // Adjust optimism based on root move's averageScore (~4 Elo) - optimism[us] = 116 * avg / (std::abs(avg) + 84); + optimism[us] = 122 * avg / (std::abs(avg) + 92); optimism[~us] = -optimism[us]; // Start with a small aspiration window and, in the case of a fail @@ -507,7 +507,7 @@ void Search::Worker::clear() { h->fill(-60); for (size_t i = 1; i < reductions.size(); ++i) - reductions[i] = int((21.69 + std::log(size_t(options["Threads"])) / 2) * std::log(i)); + reductions[i] = int((19.90 + std::log(size_t(options["Threads"])) / 2) * std::log(i)); refreshTable.clear(networks); } @@ -740,7 +740,7 @@ Value Search::Worker::search( // Use static evaluation difference to improve quiet move ordering (~9 Elo) if (((ss - 1)->currentMove).is_ok() && !(ss - 1)->inCheck && !priorCapture) { - int bonus = std::clamp(-11 * int((ss - 1)->staticEval + ss->staticEval), -1729, 1517); + int bonus = std::clamp(-11 * int((ss - 1)->staticEval + ss->staticEval), -1592, 1390); bonus = bonus > 0 ? 2 * bonus : bonus / 2; thisThread->mainHistory[~us][((ss - 1)->currentMove).from_to()] << bonus; if (type_of(pos.piece_on(prevSq)) != PAWN && ((ss - 1)->currentMove).type_of() != PROMOTION) @@ -762,7 +762,7 @@ Value Search::Worker::search( // Step 7. Razoring (~1 Elo) // If eval is really low check with qsearch if it can exceed alpha, if it can't, // return a fail low. - if (eval < alpha - 474 - 324 * depth * depth) + if (eval < alpha - 501 - 305 * depth * depth) { value = qsearch(pos, ss, alpha - 1, alpha); if (value < alpha) @@ -771,23 +771,23 @@ Value Search::Worker::search( // Step 8. Futility pruning: child node (~40 Elo) // The depth condition is important for mate finding. - if (!ss->ttPv && depth < 11 + if (!ss->ttPv && depth < 12 && eval - futility_margin(depth, cutNode && !ss->ttHit, improving, opponentWorsening) - - (ss - 1)->statScore / 252 + - (ss - 1)->statScore / 248 >= beta && eval >= beta && eval < VALUE_TB_WIN_IN_MAX_PLY && (!ttMove || ttCapture)) return beta > VALUE_TB_LOSS_IN_MAX_PLY ? (eval + beta) / 2 : eval; // Step 9. Null move search with verification search (~35 Elo) - if (!PvNode && (ss - 1)->currentMove != Move::null() && (ss - 1)->statScore < 15246 - && eval >= beta && ss->staticEval >= beta - 21 * depth + 366 && !excludedMove + if (!PvNode && (ss - 1)->currentMove != Move::null() && (ss - 1)->statScore < 13999 + && eval >= beta && ss->staticEval >= beta - 21 * depth + 390 && !excludedMove && pos.non_pawn_material(us) && ss->ply >= thisThread->nmpMinPly && beta > VALUE_TB_LOSS_IN_MAX_PLY) { assert(eval - beta >= 0); // Null move dynamic reduction based on depth and eval - Depth R = std::min(int(eval - beta) / 152, 6) + depth / 3 + 5; + Depth R = std::min(int(eval - beta) / 177, 6) + depth / 3 + 5; ss->currentMove = Move::null(); ss->continuationHistory = &thisThread->continuationHistory[0][0][NO_PIECE][0]; @@ -845,7 +845,7 @@ Value Search::Worker::search( // Step 11. ProbCut (~10 Elo) // 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 + 176 - 65 * improving; + probCutBeta = beta + 185 - 60 * improving; if ( !PvNode && depth > 3 && std::abs(beta) < VALUE_TB_WIN_IN_MAX_PLY @@ -901,7 +901,7 @@ Value Search::Worker::search( moves_loop: // When in check, search starts here // Step 12. A small Probcut idea, when we are in check (~4 Elo) - probCutBeta = beta + 440; + probCutBeta = beta + 361; if (ss->inCheck && !PvNode && ttCapture && (tte->bound() & BOUND_LOWER) && tte->depth() >= depth - 4 && ttValue >= probCutBeta && std::abs(ttValue) < VALUE_TB_WIN_IN_MAX_PLY && std::abs(beta) < VALUE_TB_WIN_IN_MAX_PLY) @@ -985,15 +985,15 @@ moves_loop: // When in check, search starts here // Futility pruning for captures (~2 Elo) if (!givesCheck && lmrDepth < 7 && !ss->inCheck) { - Value futilityValue = ss->staticEval + 276 + 256 * lmrDepth + Value futilityValue = ss->staticEval + 283 + 235 * lmrDepth + PieceValue[capturedPiece] + captHist / 7; if (futilityValue <= alpha) continue; } // SEE based pruning for captures and checks (~11 Elo) - int seeHist = std::clamp(captHist / 32, -177 * depth, 175 * depth); - if (!pos.see_ge(move, -183 * depth - seeHist)) + int seeHist = std::clamp(captHist / 32, -183 * depth, 162 * depth); + if (!pos.see_ge(move, -166 * depth - seeHist)) continue; } else @@ -1004,18 +1004,18 @@ moves_loop: // When in check, search starts here + thisThread->pawnHistory[pawn_structure_index(pos)][movedPiece][move.to_sq()]; // Continuation history based pruning (~2 Elo) - if (lmrDepth < 6 && history < -4076 * depth) + if (lmrDepth < 6 && history < -4427 * depth) continue; history += 2 * thisThread->mainHistory[us][move.from_to()]; - lmrDepth += history / 4401; + lmrDepth += history / 3670; Value futilityValue = - ss->staticEval + (bestValue < ss->staticEval - 53 ? 151 : 57) + 140 * lmrDepth; + ss->staticEval + (bestValue < ss->staticEval - 51 ? 149 : 55) + 141 * lmrDepth; // Futility pruning: parent node (~13 Elo) - if (!ss->inCheck && lmrDepth < 10 && futilityValue <= alpha) + if (!ss->inCheck && lmrDepth < 11 && futilityValue <= alpha) { if (bestValue <= futilityValue && std::abs(bestValue) < VALUE_TB_WIN_IN_MAX_PLY && futilityValue < VALUE_TB_WIN_IN_MAX_PLY) @@ -1049,11 +1049,11 @@ moves_loop: // When in check, search starts here // margins scale well. if (!rootNode && move == ttMove && !excludedMove - && depth >= 4 - (thisThread->completedDepth > 35) + ss->ttPv + && depth >= 4 - (thisThread->completedDepth > 38) + ss->ttPv && std::abs(ttValue) < VALUE_TB_WIN_IN_MAX_PLY && (tte->bound() & BOUND_LOWER) && tte->depth() >= depth - 3) { - Value singularBeta = ttValue - (57 + 50 * (ss->ttPv && !PvNode)) * depth / 64; + Value singularBeta = ttValue - (58 + 64 * (ss->ttPv && !PvNode)) * depth / 64; Depth singularDepth = newDepth / 2; ss->excludedMove = move; @@ -1063,15 +1063,15 @@ moves_loop: // When in check, search starts here if (value < singularBeta) { - int doubleMargin = 298 * PvNode - 209 * !ttCapture; - int tripleMargin = 117 + 252 * PvNode - 270 * !ttCapture + 111 * ss->ttPv; - int quadMargin = 471 + 343 * PvNode - 281 * !ttCapture + 217 * ss->ttPv; + int doubleMargin = 304 * PvNode - 203 * !ttCapture; + int tripleMargin = 117 + 259 * PvNode - 296 * !ttCapture + 97 * ss->ttPv; + int quadMargin = 486 + 343 * PvNode - 273 * !ttCapture + 232 * ss->ttPv; extension = 1 + (value < singularBeta - doubleMargin) + (value < singularBeta - tripleMargin) + (value < singularBeta - quadMargin); - depth += ((!PvNode) && (depth < 15)); + depth += ((!PvNode) && (depth < 16)); } // Multi-cut pruning @@ -1101,7 +1101,7 @@ moves_loop: // When in check, search starts here else if (PvNode && move == ttMove && move.to_sq() == prevSq && thisThread->captureHistory[movedPiece][move.to_sq()] [type_of(pos.piece_on(move.to_sq()))] - > 3748) + > 3988) extension = 1; } @@ -1157,10 +1157,10 @@ moves_loop: // When in check, search starts here ss->statScore = 2 * thisThread->mainHistory[us][move.from_to()] + (*contHist[0])[movedPiece][move.to_sq()] - + (*contHist[1])[movedPiece][move.to_sq()] - 5266; + + (*contHist[1])[movedPiece][move.to_sq()] - 5169; // Decrease/increase reduction for moves with a good/bad history (~8 Elo) - r -= ss->statScore / (14519 - std::min(depth, 15) * 103); + r -= ss->statScore / (12219 - std::min(depth, 13) * 120); // Step 17. Late moves reduction / extension (LMR, ~117 Elo) if (depth >= 2 && moveCount > 1 + rootNode) @@ -1179,7 +1179,7 @@ moves_loop: // When in check, search starts here { // Adjust full-depth search based on LMR results - if the result // was good enough search deeper, if it was bad enough search shallower. - const bool doDeeperSearch = value > (bestValue + 40 + 2 * newDepth); // (~1 Elo) + const bool doDeeperSearch = value > (bestValue + 36 + 2 * newDepth); // (~1 Elo) const bool doShallowerSearch = value < bestValue + newDepth; // (~2 Elo) newDepth += doDeeperSearch - doShallowerSearch; @@ -1340,9 +1340,9 @@ moves_loop: // When in check, search starts here // Bonus for prior countermove that caused the fail low else if (!priorCapture && prevSq != SQ_NONE) { - int bonus = (depth > 4) + (depth > 5) + (PvNode || cutNode) + ((ss - 1)->statScore < -13241) - + ((ss - 1)->moveCount > 10) + (!ss->inCheck && bestValue <= ss->staticEval - 127) - + (!(ss - 1)->inCheck && bestValue <= -(ss - 1)->staticEval - 74); + int bonus = (depth > 4) + (depth > 5) + (PvNode || cutNode) + ((ss - 1)->statScore < -14144) + + ((ss - 1)->moveCount > 9) + (!ss->inCheck && bestValue <= ss->staticEval - 115) + + (!(ss - 1)->inCheck && bestValue <= -(ss - 1)->staticEval - 81); update_continuation_histories(ss - 1, pos.piece_on(prevSq), prevSq, stat_bonus(depth) * bonus); thisThread->mainHistory[~us][((ss - 1)->currentMove).from_to()] @@ -1513,7 +1513,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta, if (bestValue > alpha) alpha = bestValue; - futilityBase = ss->staticEval + 264; + futilityBase = ss->staticEval + 279; } const PieceToHistory* contHist[] = {(ss - 1)->continuationHistory, @@ -1585,11 +1585,11 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta, + (*contHist[1])[pos.moved_piece(move)][move.to_sq()] + thisThread->pawnHistory[pawn_structure_index(pos)][pos.moved_piece(move)] [move.to_sq()] - <= 4348) + <= 4181) continue; // Do not search moves with bad enough SEE values (~5 Elo) - if (!pos.see_ge(move, -63)) + if (!pos.see_ge(move, -67)) continue; } @@ -1655,7 +1655,7 @@ Value Search::Worker::qsearch(Position& pos, Stack* ss, Value alpha, Value beta, Depth Search::Worker::reduction(bool i, Depth d, int mn, int delta) { int reductionScale = reductions[d] * reductions[mn]; - return (reductionScale + 1147 - delta * 755 / rootDelta) / 1024 + (!i && reductionScale > 1125); + return (reductionScale + 1222 - delta * 733 / rootDelta) / 1024 + (!i && reductionScale > 1231); } // elapsed() returns the time elapsed since the search started. If the @@ -1758,7 +1758,7 @@ void update_all_stats(const Position& pos, if (!pos.capture_stage(bestMove)) { - int bestMoveBonus = bestValue > beta + 165 ? quietMoveBonus // larger bonus + int bestMoveBonus = bestValue > beta + 176 ? quietMoveBonus // larger bonus : stat_bonus(depth); // smaller bonus update_quiet_stats(pos, ss, workerThread, bestMove, bestMoveBonus); @@ -1796,7 +1796,7 @@ void update_all_stats(const Position& pos, // by moves at ply -1, -2, -3, -4, and -6 with current move. void update_continuation_histories(Stack* ss, Piece pc, Square to, int bonus) { - bonus = bonus * 45 / 64; + bonus = bonus * 47 / 64; for (int i : {1, 2, 3, 4, 6}) { From 4d876275cf127b9e7cf91cef984deafa2abb47d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ste=CC=81phane=20Nicolet?= Date: Thu, 23 May 2024 22:03:43 +0200 Subject: [PATCH 08/13] Simplify material weights in evaluation This patch uses the same material weights for the nnue amplification term and the optimism term in evaluate(). STC: LLR: 2.99 (-2.94,2.94) <-1.75,0.25> Total: 83360 W: 21489 L: 21313 D: 40558 Ptnml(0-2): 303, 9934, 21056, 10058, 329 https://tests.stockfishchess.org/tests/view/664eee69928b1fb18de500d9 LTC: LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 192648 W: 48675 L: 48630 D: 95343 Ptnml(0-2): 82, 21484, 53161, 21501, 96 https://tests.stockfishchess.org/tests/view/664fa17aa86388d5e27d7d6e closes https://github.com/official-stockfish/Stockfish/pull/5287 Bench: 1495602 --- src/evaluate.cpp | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 7ca470af5..75fe0f924 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -77,13 +77,10 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, optimism += optimism * nnueComplexity / 512; nnue -= nnue * (nnueComplexity * 5 / 3) / 32082; - v = (nnue - * (32961 + 381 * pos.count() + 349 * pos.count() - + 392 * pos.count() + 649 * pos.count() + 1211 * pos.count()) - + optimism - * (4835 + 136 * pos.count() + 375 * pos.count() - + 403 * pos.count() + 628 * pos.count() + 1124 * pos.count())) - / 36860; + int material = 200 * pos.count() + 350 * pos.count() + 400 * pos.count() + + 640 * pos.count() + 1200 * pos.count(); + + v = (nnue * (34000 + material) + optimism * (4400 + material)) / 36860; // Damp down the evaluation linearly when shuffling v = v * (204 - pos.rule50_count()) / 208; From 8bc3fd3871aaa2437105bdc141d5ac25a88ea885 Mon Sep 17 00:00:00 2001 From: Linmiao Xu Date: Fri, 24 May 2024 10:58:13 -0400 Subject: [PATCH 09/13] Lower smallnet threshold with tuned eval params The smallnet threshold is now below the training data range of the current smallnet (simple eval diff > 1k, nn-baff1edelf90.nnue) when no pawns are on the board. Params found with spsa at 93k / 120k games at 60+06: https://tests.stockfishchess.org/tests/view/664fa166a86388d5e27d7d6b Tuned on top of: https://github.com/official-stockfish/Stockfish/pull/5287 Passed STC: https://tests.stockfishchess.org/tests/view/664fc8b7a86388d5e27d8dac LLR: 2.96 (-2.94,2.94) <0.00,2.00> Total: 64672 W: 16731 L: 16371 D: 31570 Ptnml(0-2): 239, 7463, 16517, 7933, 184 Passed LTC: https://tests.stockfishchess.org/tests/view/664fd5f9a86388d5e27d8dfe LLR: 2.94 (-2.94,2.94) <0.50,2.50> Total: 210648 W: 53489 L: 52813 D: 104346 Ptnml(0-2): 102, 23129, 58164, 23849, 80 closes https://github.com/official-stockfish/Stockfish/pull/5288 Bench: 1717838 --- src/evaluate.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/evaluate.cpp b/src/evaluate.cpp index 75fe0f924..13a3f2117 100644 --- a/src/evaluate.cpp +++ b/src/evaluate.cpp @@ -46,7 +46,7 @@ int Eval::simple_eval(const Position& pos, Color c) { bool Eval::use_smallnet(const Position& pos) { int simpleEval = simple_eval(pos, pos.side_to_move()); - return std::abs(simpleEval) > 1018 + 5 * pos.count(); + return std::abs(simpleEval) > 992 + 6 * pos.count(); } // Evaluate is the evaluator for the outer world. It returns a static evaluation @@ -74,13 +74,15 @@ Value Eval::evaluate(const Eval::NNUE::Networks& networks, } // Blend optimism and eval with nnue complexity - optimism += optimism * nnueComplexity / 512; - nnue -= nnue * (nnueComplexity * 5 / 3) / 32082; + optimism += optimism * nnueComplexity / 470; + nnue -= nnue * (nnueComplexity * 5 / 3) / 32621; int material = 200 * pos.count() + 350 * pos.count() + 400 * pos.count() + 640 * pos.count() + 1200 * pos.count(); - v = (nnue * (34000 + material) + optimism * (4400 + material)) / 36860; + v = (nnue * (34000 + material + 135 * pos.count()) + + optimism * (4400 + material + 99 * pos.count())) + / 35967; // Damp down the evaluation linearly when shuffling v = v * (204 - pos.rule50_count()) / 208; From 8e1f273c7d10e2b49c07cdc16b09a3d4574acf4c Mon Sep 17 00:00:00 2001 From: "Shahin M. Shahin" <41402573+peregrineshahin@users.noreply.github.com> Date: Fri, 24 May 2024 01:19:16 +0300 Subject: [PATCH 10/13] Remove rootDelta branch This makes rootDelta logic easier to understand, recalculating the value where it belongs so removes an unnecessary branch. Passed non-regression STC: https://tests.stockfishchess.org/tests/view/664fc147a86388d5e27d8d8e LLR: 2.94 (-2.94,2.94) <-1.75,0.25> Total: 206016 W: 53120 L: 53089 D: 99807 Ptnml(0-2): 591, 20928, 59888, 21061, 540 closes https://github.com/official-stockfish/Stockfish/pull/5289 No functional change --- src/search.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index 563a5710f..ed264f55c 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -330,6 +330,7 @@ void Search::Worker::iterative_deepening() { // for every four searchAgain steps (see issue #2717). Depth adjustedDepth = std::max(1, rootDepth - failedHighCnt - 3 * (searchAgainCounter + 1) / 4); + rootDelta = beta - alpha; bestValue = search(rootPos, ss, alpha, beta, adjustedDepth, false); // Bring the best move to the front. It is critical that sorting @@ -590,8 +591,6 @@ Value Search::Worker::search( if (alpha >= beta) return alpha; } - else - thisThread->rootDelta = beta - alpha; assert(0 <= ss->ply && ss->ply < MAX_PLY); From 5e98a4e43dd1c2698162bc3f848a0a98943f86c6 Mon Sep 17 00:00:00 2001 From: Shawn Xu Date: Fri, 24 May 2024 22:46:03 -0700 Subject: [PATCH 11/13] Simplify Away TT Cutoff Return Value Adjustments Passed Non-regression STC: LLR: 2.93 (-2.94,2.94) <-1.75,0.25> Total: 198432 W: 51161 L: 51119 D: 96152 Ptnml(0-2): 772, 23670, 50273, 23746, 755 https://tests.stockfishchess.org/tests/view/66517b9ea86388d5e27da966 Passed Non-regression LTC: LLR: 2.95 (-2.94,2.94) <-1.75,0.25> Total: 234150 W: 59200 L: 59197 D: 115753 Ptnml(0-2): 126, 26200, 64404, 26235, 110 https://tests.stockfishchess.org/tests/view/6653a84da86388d5e27daa63 closes https://github.com/official-stockfish/Stockfish/pull/5292 bench 1555200 --- src/search.cpp | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/search.cpp b/src/search.cpp index ed264f55c..d253601dd 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -637,9 +637,7 @@ Value Search::Worker::search( // Partial workaround for the graph history interaction problem // For high rule50 counts don't produce transposition table cutoffs. if (pos.rule50_count() < 90) - return ttValue >= beta && std::abs(ttValue) < VALUE_TB_WIN_IN_MAX_PLY - ? (ttValue * 3 + beta) / 4 - : ttValue; + return ttValue; } // Step 5. Tablebases probe From d0b9411b8275369074bb0de041257db2bccc6430 Mon Sep 17 00:00:00 2001 From: FauziAkram Date: Tue, 28 May 2024 13:49:30 +0300 Subject: [PATCH 12/13] Tweak return value in futility pruning Tweak the return value formula in futility pruning. Passed STC: LLR: 2.93 (-2.94,2.94) <0.00,2.00> Total: 60544 W: 15791 L: 15440 D: 29313 Ptnml(0-2): 193, 7024, 15520, 7309, 226 https://tests.stockfishchess.org/tests/view/6654ef22a86388d5e27db122 Passed LTC: LLR: 2.96 (-2.94,2.94) <0.50,2.50> Total: 126426 W: 32317 L: 31812 D: 62297 Ptnml(0-2): 55, 13871, 34869, 14350, 68 https://tests.stockfishchess.org/tests/view/66550644a86388d5e27db649 closes https://github.com/official-stockfish/Stockfish/pull/5295 bench: 1856147 --- src/search.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/search.cpp b/src/search.cpp index d253601dd..0dbc6a3a5 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -773,7 +773,7 @@ Value Search::Worker::search( - (ss - 1)->statScore / 248 >= beta && eval >= beta && eval < VALUE_TB_WIN_IN_MAX_PLY && (!ttMove || ttCapture)) - return beta > VALUE_TB_LOSS_IN_MAX_PLY ? (eval + beta) / 2 : eval; + return beta > VALUE_TB_LOSS_IN_MAX_PLY ? beta + (eval - beta) / 3 : eval; // Step 9. Null move search with verification search (~35 Elo) if (!PvNode && (ss - 1)->currentMove != Move::null() && (ss - 1)->statScore < 13999 From b0287dcb1c436887075962b596cf2068d2ca9ba8 Mon Sep 17 00:00:00 2001 From: Disservin Date: Tue, 28 May 2024 18:00:22 +0200 Subject: [PATCH 13/13] apply const to prefetch parameter closes https://github.com/official-stockfish/Stockfish/pull/5296 No functional change --- src/misc.cpp | 6 +++--- src/misc.h | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/misc.cpp b/src/misc.cpp index 1abb81b14..58f804204 100644 --- a/src/misc.cpp +++ b/src/misc.cpp @@ -415,14 +415,14 @@ void start_logger(const std::string& fname) { Logger::start(fname); } #ifdef NO_PREFETCH -void prefetch(void*) {} +void prefetch(const void*) {} #else -void prefetch(void* addr) { +void prefetch(const void* addr) { #if defined(_MSC_VER) - _mm_prefetch((char*) addr, _MM_HINT_T0); + _mm_prefetch((char const*) addr, _MM_HINT_T0); #else __builtin_prefetch(addr); #endif diff --git a/src/misc.h b/src/misc.h index d75b236ff..3a905dfab 100644 --- a/src/misc.h +++ b/src/misc.h @@ -40,7 +40,7 @@ std::string compiler_info(); // Preloads the given address in L1/L2 cache. This is a non-blocking // function that doesn't stall the CPU waiting for data to be loaded from memory, // which can be quite slow. -void prefetch(void* addr); +void prefetch(const void* addr); void start_logger(const std::string& fname); void* std_aligned_alloc(size_t alignment, size_t size);