Fix TT: Gains 83.0 +/- 32.5 elo

This commit is contained in:
Mattia Giambirtone 2024-05-02 19:07:20 +02:00
parent 1e06a5caef
commit 0b66f67e8c
3 changed files with 47 additions and 6 deletions

View File

@ -127,6 +127,8 @@ proc log(self: SearchManager, depth: int) =
elapsedMsec = elapsed.inMilliseconds.uint64
nps = 1000 * (self.nodeCount div max(elapsedMsec, 1))
var logMsg = &"info depth {depth} time {elapsedMsec} nodes {self.nodeCount} nps {nps}"
if not self.transpositionTable.isNil():
logMsg &= &" hashfull {self.transpositionTable.getFillEstimate()}"
if self.bestMoveRoot != nullMove():
logMsg &= &" score cp {self.bestRootScore} pv {self.bestMoveRoot.toAlgebraic()}"
echo logMsg
@ -268,8 +270,8 @@ proc search(self: SearchManager, depth, ply: int, alpha, beta: Score): Score {.d
var score: Score
var fullDepth = true
when defined(searchLMR):
if extension == 0 and i >= 3 and not move.isCapture():
# Late Move Reduction: assume our move orderer did a good job,
if extension == 0 and i >= 5 and not move.isCapture():
# Late Move Reductions: assume our move orderer did a good job,
# so it is not worth it to look at all moves at the same depth equally.
# If this move turns out to be better than we expected, we'll re-search
# it at full depth

View File

@ -44,16 +44,41 @@ type
bestMove*: Move
TTable* = ref object
## A transposition table
data: seq[TTEntry]
when defined(debug):
hits: uint64
occupancy: uint64
collisions: uint64
size: uint64
func size*(self: TTable): uint64 = self.size
when defined(debug):
func hits*(self: TTable): uint64 = self.hits
func collisions*(self: TTable): uint64 = self.collisions
func occupancy*(self: TTable): uint64 = self.occupancy
func getFillEstimate*(self: TTable): uint64 =
# For performance reasons, we estimate the occupancy by
# looking at the first 1000 entries in the table. Why 1000?
# Because the "hashfull" info message is conventionally not a
# percentage, but rather a per...millage? It's in thousandths
# rather than hundredths is the point, don't ask me why
for i in 0..999:
if self.data[i].hash != ZobristKey(0):
inc(result)
proc newTranspositionTable*(size: uint64): TTable =
## Initializes a new transposition table of
## size bytes
new(result)
let numEntries = size div sizeof(TTEntry).uint64
result.data = newSeq[TTEntry](numEntries)
result.size = numEntries
func getIndex(self: TTable, key: ZobristKey): uint64 =
@ -71,7 +96,15 @@ func getIndex(self: TTable, key: ZobristKey): uint64 =
func store*(self: TTable, depth: uint8, score: Score, hash: ZobristKey, bestMove: Move, flag: TTentryFlag) =
## Stores an entry in the transposition table
self.data[self.getIndex(hash)] = TTEntry(flag: flag, score: int16(score), hash: hash, depth: depth, bestMove: bestMove)
when defined(debug):
let idx = self.getIndex(hash)
if self.data[idx].hash != ZobristKey(0):
inc(self.collisions)
else:
inc(self.occupancy)
self.data[idx] = TTEntry(flag: flag, score: int16(score), hash: hash, depth: depth, bestMove: bestMove)
else:
self.data[self.getIndex(hash)] = TTEntry(flag: flag, score: int16(score), hash: hash, depth: depth, bestMove: bestMove)
proc get*(self: TTable, hash: ZobristKey, depth: uint8): tuple[success: bool, entry: TTEntry] =
@ -83,6 +116,9 @@ proc get*(self: TTable, hash: ZobristKey, depth: uint8): tuple[success: bool, en
## it's true
result.entry = self.data[self.getIndex(hash)]
result.success = result.entry.hash == hash and result.entry.depth >= depth
when defined(debug):
if result.success:
inc(self.hits)
proc get*(self: TTable, hash: ZobristKey): tuple[success: bool, entry: TTEntry] =
@ -92,4 +128,7 @@ proc get*(self: TTable, hash: ZobristKey): tuple[success: bool, entry: TTEntry]
## or other anomaly: the result should be considered
## invalid unless it's true
result.entry = self.data[self.getIndex(hash)]
result.success = result.entry.hash == hash
result.success = result.entry.hash == hash
when defined(debug):
if result.success:
inc(self.hits)

View File

@ -354,10 +354,10 @@ proc startUCISession* =
session.board = newDefaultChessboard()
of Go:
when defined(useTT):
if session.transpositionTable.isNil():
if session.transpositionTable.isNil() or session.transpositionTable.size() == 0:
session.transpositionTable = newTranspositionTable(session.hashTableSize * 1024 * 1024)
if session.debug:
echo &"info string created {session.hashTableSize} MiB TT"
session.transpositionTable = newTranspositionTable(session.hashTableSize * 1024 * 1024)
session.searchThread = new Thread[tuple[session: UCISession, command: UCICommand]]
createThread(session.searchThread[], bestMove, (session, cmd))
if session.debug: