summaryrefslogtreecommitdiff
path: root/src/hash.c
diff options
context:
space:
mode:
authorScott Gasch <[email protected]>2026-10-09 14:18:52 -0700
committerScott Gasch <[email protected]>2026-10-09 14:18:52 -0700
commitfbdcb9d76dd2444d8bc631331eaeb9435cc247f8 (patch)
tree602ab360462d6f23188ba51f962c4abb2dc6c7e5 /src/hash.c
parent73b4afb12abf7cc442831dea42b41b63a2ce07be (diff)
* Grab bag of eval.c changes.
* Don't bother not hashing when moves are pruned. * Prune moves move librerally with LMP. Inexplicably, this is slightly shallower than HEAD (despite pruning MORE). It may be because it is slightly slower. It consistently beats HEAD in match_play.py though (3x now).
Diffstat (limited to 'src/hash.c')
-rw-r--r--src/hash.c90
1 files changed, 41 insertions, 49 deletions
diff --git a/src/hash.c b/src/hash.c
index 887b6a1..28d85cd 100644
--- a/src/hash.c
+++ b/src/hash.c
@@ -8,20 +8,20 @@ Module Name:
Abstract:
- The main transposition table code. The table is a large range of
+ The main transposition table code. The table is a large range of
memory organized into lines (64 bytes). Each line contains four
entries that are 16 bytes each (index 0..3).
-
+
After a search, data about the position's score and the depth we
searched to determine this score can be stored in the hash table.
When information is stored a hash replacement scheme is used to
overwrite one of the four entries on a line.
-
+
Later, before embarking on a deep recursive search, we can check
- the hash table to see if information relevant to this position
+ the hash table to see if information relevant to this position
has been stored already (and can be reused). If so, we can avoid
repeating the same search and save time.
-
+
A hash entry is 16 bytes long and looks like this:
typedef struct _HASH_ENTRY
@@ -74,7 +74,7 @@ Abstract:
When screwing around with the hash code, turn on PERF_COUNTERS and
watch the hash hit rate (and usable hash hit rate). Also here is
Fine position #70 which is a great sanity check for hash code:
-
+
8/k7/3p4/p2P1p2/P2P1P2/8/8/K7/ w - - 0 0 bm 1. Ka1-b1 Ka7-b7 2. Kb1-c1
Author:
@@ -104,7 +104,7 @@ Revision History:
#define HASH_ENTRY_IS_DIRTY(x) \
(((x).bvFlags & 0xF0) != g_cDirty)
-
+
#undef ADJUST_MATE_IN_N
ULONG g_uHashTableSizeEntries = 0;
@@ -112,15 +112,15 @@ ULONG g_uHashTableSizeBytes = 0;
HASH_ENTRY *g_pHashTable = NULL;
UCHAR g_cDirty = 0;
-void
+void
DirtyHashTable(void)
/**
Routine description:
- The dirty pattern is bitwise ored onto the bvFlags part of a
+ The dirty pattern is bitwise ored onto the bvFlags part of a
hash table entry. Since the low nibble is used to hold flags
- like upper bound, lower bound, exact score, and threat the
+ like upper bound, lower bound, exact score, and threat the
dirty indicator is limited to operating in the upper nibble
of bvFlags (giving it a range of 16 values)
@@ -146,13 +146,13 @@ Return value:
}
-void
+void
CleanupHashSystem(void)
/**
Routine description:
- Cleanup the hash table by freeing the memory and zeroing some
+ Cleanup the hash table by freeing the memory and zeroing some
variables. This is called before building an opening book in
order to free some virtual address space up.
@@ -176,7 +176,7 @@ Return value:
}
}
-FLAG
+FLAG
InitializeHashSystem(void)
/**
@@ -196,11 +196,11 @@ Return value:
**/
{
ULONG uBytesToAlloc;
-
+
if (!IS_A_POWER_OF_2(g_Options.uNumHashTableEntries))
{
return(FALSE);
- }
+ }
g_uHashTableSizeEntries = g_Options.uNumHashTableEntries;
if (g_uHashTableSizeEntries != 0)
{
@@ -214,8 +214,8 @@ Return value:
}
-void
-ClearHashTable (void)
+void
+ClearHashTable (void)
/**
Routine description:
@@ -398,9 +398,9 @@ Return value:
}
-void
-StoreUpperBound(//MOVE mvBest,
- POSITION *pos,
+void
+StoreUpperBound(//MOVE mvBest,
+ POSITION *pos,
SCORE iValue,
ULONG uDepth,
FLAG fThreat)
@@ -426,10 +426,10 @@ Return value:
{
UINT64 u64Key;
HASH_ENTRY *pHash;
-
+
ASSERT(IS_VALID_SCORE(iValue));
ASSERT(IS_VALID_DEPTH(uDepth));
-
+
//
// It does not make sense to store hash positions that are worth
// at best ~INFINITY_SCORE. Every position is and this is a waste of
@@ -491,19 +491,19 @@ Return value:
}
-void
-StoreExactScore(MOVE mvBestMove,
- POSITION *pos,
- SCORE iValue,
- ULONG uDepth,
- FLAG fThreat,
+void
+StoreExactScore(MOVE mvBestMove,
+ POSITION *pos,
+ SCORE iValue,
+ ULONG uDepth,
+ FLAG fThreat,
ULONG uPly)
/**
-
+
Routine description:
Store a best move and its exact score in the hash table.
-
+
Parameters:
MOVE mvBestMove,
@@ -521,7 +521,7 @@ Return value:
{
HASH_ENTRY *pHash;
UINT64 u64Key;
-
+
ASSERT(IS_VALID_SCORE(iValue));
ASSERT(IS_VALID_DEPTH(uDepth));
if (NULL == g_pHashTable) return;
@@ -585,11 +585,11 @@ Return value:
}
-void
-StoreLowerBound(MOVE mvBestMove,
- POSITION *pos,
+void
+StoreLowerBound(MOVE mvBestMove,
+ POSITION *pos,
SCORE iValue,
- ULONG uDepth,
+ ULONG uDepth,
FLAG fThreat)
/**
@@ -621,10 +621,10 @@ Return value:
// Do not bother to hash this node if it is telling us that the
// value of this position is worth at least ~-INFINITY_SCORE. This is
// useless information and a waste of hash space.
- //
+ //
if (iValue <= -NMATE) return;
if (NULL == g_pHashTable) return;
-
+
CONVERT_SEARCH_DEPTH_TO_HASH_DEPTH(uDepth);
u64Key = pos->u64NonPawnSig ^ pos->u64PawnSig;
@@ -678,7 +678,7 @@ Return value:
}
-MOVE
+MOVE
GetPonderMove(POSITION *pos)
/**
@@ -700,7 +700,7 @@ Return value:
ULONG x;
UINT64 u64Key = pos->u64NonPawnSig ^ pos->u64PawnSig;
MOVE mv;
-
+
mv.uMove = 0;
if (NULL == g_pHashTable) return(mv);
@@ -789,7 +789,7 @@ Return value:
ULONG uMoveScore = 0;
ULONG uThisScore;
FLAG fFoundUsableBound = FALSE;
-
+
#define COMPUTE_MOVE_SCORE(mv, depth) \
((depth) * 8 + PIECE_VALUE_OVER_100((mv).pCaptured) + 1)
@@ -858,15 +858,7 @@ Return value:
//
*pfThreat |= ((sLocal.bvFlags & HASH_FLAG_THREAT) > 0);
- //
- // If we have an exact match and sufficient depth to
- // satisfy the depth to which we will later search after a
- // nullmove, see if the known value of this node is less
- // than beta. If so, doing nothing in this position will
- // probably not be better than doing something therefore
- // its not wise to perform the nullmove search. It's just
- // a waste of nodes and time.
- //
+ // See if we can advise against performing a nullmove search.
if ((sLocal.uDepth >= uNextDepth) &&
((sLocal.bvFlags & HASH_FLAG_UPPER) ||
(sLocal.bvFlags & HASH_FLAG_EXACT)) &&