summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/GNUmakefile6
-rwxr-xr-xsrc/chess.h55
-rwxr-xr-xsrc/eval.c44
-rw-r--r--src/evalhash.c173
-rwxr-xr-xsrc/main.c7
-rwxr-xr-xsrc/root.c2
-rwxr-xr-xsrc/search.c3
-rwxr-xr-xsrc/split.c4
-rwxr-xr-xsrc/testeval.c1
9 files changed, 21 insertions, 274 deletions
diff --git a/src/GNUmakefile b/src/GNUmakefile
index dbb74cf..ef80e95 100644
--- a/src/GNUmakefile
+++ b/src/GNUmakefile
@@ -4,7 +4,6 @@
# TEST=1: include self-test code in the binary produced
# ASM=1: create assembly code, does not link final binary
# EVAL_DUMP=1: make a version that can dump eval breakdowns
-# EVAL_HASH=1: hash eval scores
# EVAL_TIME=1: make a version that counts cycles spent in eval
# PERF_COUNTERS=1: make version with perf counters enabled
# BOUNDS_CHECKING=1: make version with bounds checking enabled
@@ -91,14 +90,11 @@ ifdef CROUTINES
endif
ifdef EVERYTHING
-PROFILE += -DEVAL_DUMP -DEVAL_HASH -DEVAL_TIME -DPERF_COUNTERS -DMP -DSMP -DTEST_NULL -DDUMP_TREE -fbounds-checking
+PROFILE += -DEVAL_DUMP -DEVAL_TIME -DPERF_COUNTERS -DMP -DSMP -DTEST_NULL -DDUMP_TREE -fbounds-checking
else
ifdef EVAL_DUMP
PROFILE += -DEVAL_DUMP
endif
-ifdef EVAL_HASH
-PROFILE += -DEVAL_HASH
-endif
ifdef EVAL_TIME
PROFILE += -DEVAL_TIME
endif
diff --git a/src/chess.h b/src/chess.h
index 9689189..630f090 100755
--- a/src/chess.h
+++ b/src/chess.h
@@ -907,7 +907,6 @@ typedef struct _SPLIT_INFO
INT iPositionExtend; // positional extension
SCORE iAlpha; // original alpha at split
SCORE iBeta; // beta at split
- ULONG uSplitPositional; // pos->uPositional at split
CUMULATIVE_SEARCH_FLAGS sSearchFlags; // flags at split time
// output from the split node
@@ -953,38 +952,6 @@ typedef struct _PLY_INFO
}
PLY_INFO;
-// #define EVAL_HASH
-#ifdef EVAL_HASH
-#define EVAL_HASH_TABLE_SIZE (2097152) // 32Mb (per thread)
-
-//
-// bvFlags values for EVAL_HASH_ENTRY. EXACT means iEval is the real,
-// fully-computed static eval. UPPER/LOWER mean the entry came from a
-// lazy-eval early exit: iEval is the (uncorrected) partial score that
-// would be returned and iBound is the proven bound on the true, fully
-// computed eval (true score <= iBound for UPPER, true score >= iBound
-// for LOWER). Because the bound is a fact about the position -- not
-// about whatever alpha/beta window triggered the lazy exit -- it can
-// be reused by a later probe with a different window, as long as that
-// window is still resolved by the bound (mirrors HASH_FLAG_UPPER /
-// HASH_FLAG_LOWER in the main hash table).
-//
-#define EVAL_HASH_EXACT 0x1
-#define EVAL_HASH_UPPER 0x2
-#define EVAL_HASH_LOWER 0x4
-
-typedef struct _EVAL_HASH_ENTRY
-{
- UINT64 u64Key;
- SCORE iEval;
- SCORE iBound;
- UCHAR bvFlags;
- ULONG uPositional;
- COOR cTrapped[2];
-
-} EVAL_HASH_ENTRY;
-#endif
-
#define PAWN_HASH_TABLE_SIZE (131072) // 5.5Mb (per thread)
typedef struct _PAWN_HASH_ENTRY
{
@@ -1014,7 +981,6 @@ PAWN_HASH_ENTRY;
typedef struct _SEARCHER_THREAD_CONTEXT
{
ULONG uPly; // its distance from root
- ULONG uPositional; // positional component of score
POSITION sPosition; // the board
MOVE_STACK sMoveStack; // the move stack
CUMULATIVE_SEARCH_FLAGS sSearchFlags;
@@ -1035,9 +1001,6 @@ typedef struct _SEARCHER_THREAD_CONTEXT
SCORE iRootScore;
ULONG uRootDepth;
PAWN_HASH_ENTRY rgPawnHash[PAWN_HASH_TABLE_SIZE];
-#ifdef EVAL_HASH
- EVAL_HASH_ENTRY rgEvalHash[EVAL_HASH_TABLE_SIZE];
-#endif
CHAR szLastPV[SMALL_STRING_LEN_CHAR];
}
SEARCHER_THREAD_CONTEXT;
@@ -1060,7 +1023,6 @@ SEARCHER_THREAD_CONTEXT;
typedef struct _LIGHTWEIGHT_SEARCHER_CONTEXT
{
ULONG uPly;
- ULONG uPositional;
POSITION sPosition;
MOVE_STACK sMoveStack;
CUMULATIVE_SEARCH_FLAGS sSearchFlags;
@@ -2309,7 +2271,7 @@ IsDraw(SEARCHER_THREAD_CONTEXT *ctx);
// search.c
//
#define QPLIES_OF_NON_CAPTURE_CHECKS (2)
-#define FUTILITY_BASE_MARGIN (50) // + ctx->uPositional (min 100)
+#define FUTILITY_BASE_MARGIN (50)
#define DO_IID
#define IID_R_FACTOR (TWO_PLY + HALF_PLY)
@@ -3029,25 +2991,10 @@ RecognLookup(SEARCHER_THREAD_CONTEXT *ctx,
SCORE *piScore,
FLAG fProbeEGTB);
-#ifdef EVAL_HASH
-void
-ClearEvalHashStats(void);
-
-void
-ReportEvalHashStats(void);
-
-SCORE
-ProbeEvalHash(SEARCHER_THREAD_CONTEXT *ctx, SCORE iAlpha, SCORE iBeta);
-
SCORE
GetRoughEvalScore(IN SEARCHER_THREAD_CONTEXT *ctx,
IN SCORE iAlpha,
IN SCORE iBeta,
IN FLAG fUseHash);
-void
-StoreEvalHash(SEARCHER_THREAD_CONTEXT *ctx, SCORE iScore, SCORE iBound,
- UCHAR bvFlags);
-#endif // EVAL_HASH
-
#endif // CHESS
diff --git a/src/eval.c b/src/eval.c
index 99baf8a..cf9527b 100755
--- a/src/eval.c
+++ b/src/eval.c
@@ -5561,18 +5561,6 @@ Return value:
pos->uMinMobility[BLACK] = pos->uMinMobility[WHITE] = 100;
pos->cTrapped[BLACK] = pos->cTrapped[WHITE] = ILLEGAL_COOR;
-#ifdef EVAL_HASH
- //
- // Check the eval hash
- //
- iScoreForSideToMove = ProbeEvalHash(ctx, iAlpha, iBeta);
- if (iScoreForSideToMove != INVALID_SCORE)
- {
- INC(ctx->sCounters.tree.u64EvalHashHits);
- goto end;
- }
-#endif
-
pos->iScore[BLACK] =
(pos->uPawnMaterial[BLACK] + pos->uNonPawnMaterial[BLACK]);
pos->iScore[WHITE] =
@@ -5690,16 +5678,6 @@ Return value:
{
*piPositional = iAlphaMargin;
}
-#ifdef EVAL_HASH
- //
- // The true eval can't reach iAlpha; that's a fact about
- // the position (not this particular window), so remember
- // it as a proven upper bound for reuse by later probes.
- //
- StoreEvalHash(ctx, iScoreForSideToMove,
- (SCORE)(iScoreForSideToMove + iAlphaMargin),
- EVAL_HASH_UPPER);
-#endif
goto end;
}
else if (iScoreForSideToMove - iBetaMargin >= iBeta)
@@ -5709,11 +5687,6 @@ Return value:
{
*piPositional = iBetaMargin;
}
-#ifdef EVAL_HASH
- StoreEvalHash(ctx, iScoreForSideToMove,
- (SCORE)(iScoreForSideToMove - iBetaMargin),
- EVAL_HASH_LOWER);
-#endif
goto end;
}
}
@@ -6090,15 +6063,6 @@ Return value:
{
*piPositional = iAlphaMargin;
}
- if ((ULONG)iAlphaMargin > ctx->uPositional)
- {
- ctx->uPositional = (ULONG)iAlphaMargin;
- }
- else
- {
- ctx->uPositional -= (ctx->uPositional - (ULONG)iAlphaMargin) / 4;
- ctx->uPositional = MAXU(ctx->uPositional, VALUE_PAWN);
- }
g_Options.iLastEvalScore = iScoreForSideToMove;
#ifdef EVAL_TIME
@@ -6107,13 +6071,6 @@ Return value:
#endif
INC(ctx->sCounters.tree.u64FullEvals);
-#ifdef EVAL_HASH
- //
- // Store in eval hash.
- //
- StoreEvalHash(ctx, iScoreForSideToMove, 0, EVAL_HASH_EXACT);
-#endif
-
end:
ASSERT(IS_VALID_SCORE(iScoreForSideToMove));
ASSERT((iScoreForSideToMove > -NMATE) &&
@@ -6122,6 +6079,5 @@ Return value:
ASSERT(abs(ctx->sPlyInfo[ctx->uPly].iKingScore[WHITE]) < 700);
ASSERT(ctx->sPlyInfo[ctx->uPly].uMinMobility[BLACK] <= 100);
ASSERT(ctx->sPlyInfo[ctx->uPly].uMinMobility[WHITE] <= 100);
- ASSERT((ctx->uPositional < 2500) && (ctx->uPositional >= VALUE_PAWN));
return(iScoreForSideToMove);
}
diff --git a/src/evalhash.c b/src/evalhash.c
index fc29b88..4df6e23 100644
--- a/src/evalhash.c
+++ b/src/evalhash.c
@@ -8,7 +8,11 @@ Module Name:
Abstract:
- Evaluation score hashing code.
+ Rough (mid-tree) eval estimation. Used to hold the eval-score
+ hashing code (EVAL_HASH) too; that subsystem was cut for good
+ (measured as slow as or slower than just computing eval) and is
+ not coming back in this form, so this file is now just
+ GetRoughEvalScore().
Author:
@@ -20,8 +24,6 @@ Revision History:
#include "chess.h"
-extern ULONG g_uIterateDepth;
-
SCORE
GetRoughEvalScore(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
IN SCORE iAlpha,
@@ -34,23 +36,22 @@ Routine description:
This is meant to be the "one place" that code looks when it needs to
get an idea of the estimated evaluation of a position (in mid tree,
not at the leaves... at the leaves just call Eval directly).
-
- The thought is that:
-
- 1. The top of the tree (near the root) represents very few nodes
- which have big subtrees. Use the real Eval here.
-
- 2. Otherwise possibly probe the eval hash -- if there's a score in
- it then we can return quickly.
-
- 3. Otherwise do a (very) rough material estimate.
+
+ Just calls Eval() -- its own lazy-exit machinery already is the
+ cheap, calibrated estimate this function exists to provide, so
+ there's no separate "rough" estimator to maintain here. Used to
+ fall back to material + a stale ctx->uPositional EWMA left over
+ from whatever full eval last ran anywhere in the tree, fed by an
+ eval-hash probe (fUseHash); both are gone now (see the commit
+ removing ctx->uPositional and EVAL_HASH), and this is the direct
+ replacement.
Parameters:
IN OUT SEARCHER_THREAD_CONTEXT *ctx,
IN SCORE iAlpha,
IN SCORE iBeta,
- IN FLAG fUseHash
+ IN FLAG fUseHash : unused, kept for call-site compatibility
Return value:
@@ -58,148 +59,6 @@ Return value:
--*/
{
- POSITION *pos = &(ctx->sPosition);
- UINT64 u64Key;
- ULONG u;
-
- if (ctx->uPly <= 4)
- {
- return Eval(ctx, iAlpha, iBeta, NULL);
- }
-#ifdef EVAL_HASH
- else if ((fUseHash) || (ctx->uPly <= (g_uIterateDepth / 2)))
- {
- u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig);
- u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1);
- if (ctx->rgEvalHash[u].u64Key == u64Key)
- {
- switch(ctx->rgEvalHash[u].bvFlags)
- {
- case EVAL_HASH_EXACT:
- ctx->uPositional = ctx->rgEvalHash[u].uPositional;
- return(ctx->rgEvalHash[u].iEval);
- case EVAL_HASH_UPPER:
- if (ctx->rgEvalHash[u].iBound <= iAlpha)
- {
- return(ctx->rgEvalHash[u].iEval);
- }
- break;
- case EVAL_HASH_LOWER:
- if (ctx->rgEvalHash[u].iBound >= iBeta)
- {
- return(ctx->rgEvalHash[u].iEval);
- }
- break;
- }
- }
- }
-#else
- (void)u64Key;
- (void)u;
(void)fUseHash;
-#endif
- return(pos->iMaterialBalance[pos->uToMove] + ctx->uPositional);
-}
-
-#ifdef EVAL_HASH
-
-
-SCORE
-ProbeEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx, IN SCORE iAlpha, IN SCORE iBeta)
-/*++
-
-Routine description:
-
- Probe the eval hash; return a real score if there's a hit
- otherwise return INVALID_SCORE. An EXACT entry is always usable.
- An UPPER/LOWER entry (recorded from a lazy-eval early exit) is
- only usable if the bound it proved still resolves the caller's
- current alpha/beta window; otherwise it's treated as a miss and
- the caller must actually compute something.
-
-Parameters:
-
- IN OUT SEARCHER_THREAD_CONTEXT *ctx : note that in the case
- of a hit, *ctx is modified also.
- IN SCORE iAlpha, IN SCORE iBeta : caller's current window
-
-Return value:
-
- SCORE
-
---*/
-{
- POSITION *pos = &(ctx->sPosition);
- UINT64 u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig);
- ULONG u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1);
-
- if (ctx->rgEvalHash[u].u64Key == u64Key)
- {
- switch(ctx->rgEvalHash[u].bvFlags)
- {
- case EVAL_HASH_EXACT:
- ctx->uPositional = ctx->rgEvalHash[u].uPositional;
- pos->cTrapped[WHITE] = ctx->rgEvalHash[u].cTrapped[WHITE];
- pos->cTrapped[BLACK] = ctx->rgEvalHash[u].cTrapped[BLACK];
- return(ctx->rgEvalHash[u].iEval);
- case EVAL_HASH_UPPER:
- if (ctx->rgEvalHash[u].iBound <= iAlpha)
- {
- return(ctx->rgEvalHash[u].iEval);
- }
- break;
- case EVAL_HASH_LOWER:
- if (ctx->rgEvalHash[u].iBound >= iBeta)
- {
- return(ctx->rgEvalHash[u].iEval);
- }
- break;
- }
- }
- return(INVALID_SCORE);
-}
-
-void
-StoreEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx,
- IN SCORE iScore,
- IN SCORE iBound,
- IN UCHAR bvFlags)
-/*++
-
-Routine description:
-
- Store a score in the eval hash table (which is pointed to
- indirectly via ctx). bvFlags is EVAL_HASH_EXACT for a fully
- computed eval (iBound ignored) or EVAL_HASH_UPPER/EVAL_HASH_LOWER
- for a bound proven by a lazy-eval early exit (iScore is the
- uncorrected partial score that would be returned, iBound is the
- proven bound on the true eval).
-
-Parameters:
-
- SEARCHER_THREAD_CONTEXT *ctx,
- SCORE iScore,
- SCORE iBound,
- UCHAR bvFlags
-
-Return value:
-
- void
-
---*/
-{
- POSITION *pos = &(ctx->sPosition);
- UINT64 u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig);
- ULONG u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1);
- ctx->rgEvalHash[u].u64Key = u64Key;
- ctx->rgEvalHash[u].iEval = iScore;
- ctx->rgEvalHash[u].iBound = iBound;
- ctx->rgEvalHash[u].bvFlags = bvFlags;
- if (bvFlags == EVAL_HASH_EXACT)
- {
- ctx->rgEvalHash[u].uPositional = ctx->uPositional;
- ctx->rgEvalHash[u].cTrapped[WHITE] = pos->cTrapped[WHITE];
- ctx->rgEvalHash[u].cTrapped[BLACK] = pos->cTrapped[BLACK];
- }
+ return Eval(ctx, iAlpha, iBeta, NULL);
}
-#endif // EVAL_HASH
diff --git a/src/main.c b/src/main.c
index 52e1bb6..3267da6 100755
--- a/src/main.c
+++ b/src/main.c
@@ -79,16 +79,9 @@ Return value:
#ifdef DUMP_TREE
Trace(" Search tree dumpfile generation enabled\n");
#endif
-#ifdef EVAL_HASH
- Trace(" Hash sizes: %u Mb (main), %u Mb / thread (pawn), %u Mb / thread (eval)\n",
- (g_uHashTableSizeEntries * sizeof(HASH_ENTRY)) / MB,
- PAWN_HASH_TABLE_SIZE * sizeof(PAWN_HASH_ENTRY) / MB,
- EVAL_HASH_TABLE_SIZE * sizeof(EVAL_HASH_ENTRY) / MB);
-#else
Trace(" Hash sizes: %u Mb (main), %u Mb / thread (pawn)\n",
(g_uHashTableSizeEntries * sizeof(HASH_ENTRY)) / MB,
PAWN_HASH_TABLE_SIZE * sizeof(PAWN_HASH_ENTRY) / MB);
-#endif
Trace(" QCheckPlies: %u\n", QPLIES_OF_NON_CAPTURE_CHECKS);
Trace(" FutilityBase: %u\n", FUTILITY_BASE_MARGIN);
p = ExportEvalDNA();
diff --git a/src/root.c b/src/root.c
index a83249c..a651c71 100755
--- a/src/root.c
+++ b/src/root.c
@@ -296,7 +296,6 @@ Return value:
memmove(&(ctx->sPosition), pos, sizeof(POSITION));
}
ctx->uPly = 0;
- ctx->uPositional = 133;
memset(&(ctx->sCounters), 0, sizeof(COUNTERS));
}
@@ -375,7 +374,6 @@ Return value:
memmove(&(ctx->sPosition), pos, sizeof(POSITION));
}
ctx->uPly = 0;
- ctx->uPositional = 133;
ctx->sMoveStack.uUnblockedKeyValue[0] = 1;
for (u = 1;
u < MAX_PLY_PER_SEARCH;
diff --git a/src/search.c b/src/search.c
index ce867b6..6c8a945 100755
--- a/src/search.c
+++ b/src/search.c
@@ -1147,7 +1147,8 @@ QSearch(IN SEARCHER_THREAD_CONTEXT *ctx,
// set and valid, it means this is not a "quiet" position. If the
// side on the move has not been able to stand pat yet, don't let
// them now -- force them to play a move and recurse.
- if (0 != ValueOfMaterialInTroubleDespiteMove(ctx, pos->uToMove))
+ if (0 != ValueOfMaterialInTroubleDespiteMove(ctx, pos->uToMove) &&
+ FALSE == ctx->sSearchFlags.fCouldStandPat[pos->uToMove])
{
iBestScore = iAlpha;
}
diff --git a/src/split.c b/src/split.c
index 2672c0c..8558e3c 100755
--- a/src/split.c
+++ b/src/split.c
@@ -182,8 +182,7 @@ Return value:
uIdleLoops = 0;
ReInitializeSearcherContext(&(g_SplitInfo[u].sRootPosition), ctx);
ctx->pSplitInfo[0] = &(g_SplitInfo[u]);
- ctx->uPositional = g_SplitInfo[u].uSplitPositional;
-
+
//
// Note: the main thread could have already exhausted the
// split and decremented it from 3->2. When we leave it
@@ -597,7 +596,6 @@ Return value:
g_SplitInfo[u].iPositionExtend = iPositionExtend;
g_SplitInfo[u].iAlpha = *piAlpha;
g_SplitInfo[u].iBeta = iBeta;
- g_SplitInfo[u].uSplitPositional = ctx->uPositional;
g_SplitInfo[u].sSearchFlags = ctx->sSearchFlags;
ASSERT(FALSE == ctx->sSearchFlags.fAvoidNullmove);
g_SplitInfo[u].mvBest = *pmvBest;
diff --git a/src/testeval.c b/src/testeval.c
index 0c4b1cf..ee9c6a2 100755
--- a/src/testeval.c
+++ b/src/testeval.c
@@ -422,7 +422,6 @@ Return value:
u < ARRAY_LENGTH(x);
u++)
{
- ctx.uPositional = 0;
if (FALSE == FenToPosition(&(ctx.sPosition), x[u].szFen))
{
UtilPanic(INCONSISTENT_STATE,