Re: stockfish fail high fail low
Posted: Tue Jul 06, 2010 12:10 am
My last report on Stockfish 1.7.1, because 1.8 is out there with search.cpp nicer then ever. Majority of tests I tried were inconclusive and I was needing more computer time for my correspondence chess, but there are two ideas about null move search.
First idea is about what to return when we have nullValue>=beta. When testing 4 different patches to improve stability (round robin of matches of 1000 games repeating from first 500 gaviota starters), the best with +5(+-7) elo over original stockfish (los 81:18) was this patchwith the guiding idea that when search() returns something, it should return the same thing also when beta is less far from that. Razoring was well commented, but null move search was not.
When I saw that I am not getting stability, just elo, I focused more on null move search. So I asked myself, why do we do verification search with reduction of 5*OnePly when null move search was reduced by R*OnePly? Patch:And to keep notebook busy at weekend, I also combined R+2 verification with nullValue bound to third patch:LOS of second patch against original was 96:3, third patch against original had los 75:24, but in direct confrontation the third one was better with LOS 58:41. When I joined the 3 pgn files together, bayeselo changed this 3 ratios to 94:5, 91:8 and 40:59 respectively.
First idea is about what to return when we have nullValue>=beta. When testing 4 different patches to improve stability (round robin of matches of 1000 games repeating from first 500 gaviota starters), the best with +5(+-7) elo over original stockfish (los 81:18) was this patch
Code: Select all
diff -dur src-Ch/search.cpp src-Pv6Ch/search.cpp
--- src-Ch/search.cpp 2010-04-20 00:45:49.000000000 +0200
+++ src-Pv6Ch/search.cpp 2010-06-19 19:15:20.000000000 +0200
@@ -1334,7 +1334,8 @@
if (v < rbeta)
// Logically we should return (v + razor_margin(depth)), but
// surprisingly this did slightly weaker in tests.
- return v;
+ //return v;
+ return v + razor_margin(depth);
}
// Step 7. Static null move pruning
@@ -1387,6 +1388,18 @@
&& !AbortSearch
&& !TM.thread_should_stop(threadID))
{
+ // Reduce nullValue to not contradict null move conditions when used as lower bound.
+ if (beta < refinedValue - PawnValueMidgame)
+ {
+ if (nullValue >= refinedValue - PawnValueMidgame)
+ nullValue = Max(beta, refinedValue - PawnValueMidgame - 4);
+ }
+ else
+ {
+ nullValue = Min(nullValue, refinedValue + (depth >= 4 * OnePly ? NullMoveMargin : 0));
+ assert(nullValue >= beta);
+ }
+
assert(value_to_tt(nullValue, ply) == nullValue);
TT.store(posKey, nullValue, VALUE_TYPE_NS_LO, depth, MOVE_NONE);
When I saw that I am not getting stability, just elo, I focused more on null move search. So I asked myself, why do we do verification search with reduction of 5*OnePly when null move search was reduced by R*OnePly? Patch:
Code: Select all
diff -dur src-Ch/search.cpp src-Nmv0Ch/search.cpp
--- src-Ch/search.cpp 2010-04-20 00:45:49.000000000 +0200
+++ src-Nmv0Ch/search.cpp 2010-07-01 22:44:01.000000000 +0200
@@ -1382,8 +1382,8 @@
// Do zugzwang verification search for high depths, don't store in TT
// if search was stopped.
- if ( ( depth < 6 * OnePly
- || search(pos, ss, beta, depth-5*OnePly, ply, false, threadID) >= beta)
+ if ( ( depth-(R+2)*OnePly < OnePly
+ || search(pos, ss, beta, depth-(R+2)*OnePly, ply, false, threadID) >= beta)
&& !AbortSearch
&& !TM.thread_should_stop(threadID))
{
Code: Select all
diff -dur src-Ch/search.cpp src-Nmv1Ch/search.cpp
--- src-Ch/search.cpp 2010-04-20 00:45:49.000000000 +0200
+++ src-Nmv1Ch/search.cpp 2010-07-01 22:43:59.000000000 +0200
@@ -1376,14 +1376,24 @@
if (nullValue >= beta)
{
+ // Reduce nullValue to not contradict null move conditions when used as lower bound.
+ if (beta < refinedValue - PawnValueMidgame)
+ {
+ if (nullValue >= refinedValue - PawnValueMidgame)
+ nullValue = Max(beta, refinedValue - PawnValueMidgame - 8);
+ }
+ else
+ {
+ nullValue = Min(nullValue, refinedValue + (depth >= 4 * OnePly ? NullMoveMargin : 0));
+ assert(nullValue >= beta);
+ }
// Do not return unproven mate scores
- if (nullValue >= value_mate_in(PLY_MAX))
- nullValue = beta;
+ assert(nullValue < value_mate_in(PLY_MAX));
// Do zugzwang verification search for high depths, don't store in TT
// if search was stopped.
- if ( ( depth < 6 * OnePly
- || search(pos, ss, beta, depth-5*OnePly, ply, false, threadID) >= beta)
+ if ( ( depth-(R+2)*OnePly < OnePly
+ || search(pos, ss, beta, depth-(R+2)*OnePly, ply, false, threadID) >= beta)
&& !AbortSearch
&& !TM.thread_should_stop(threadID))
{