Adds optional multithreaded search behind a thread count that defaults to
1, so the live bot's play is unchanged until explicitly configured.
- ParallelSearch runs N AlphaBetaSearch workers over one shared,
already-lock-protected TranspositionTable. Each worker has its own NNUE
evaluator (independent accumulator) and ordering state; helpers only
deepen the shared TT, the main worker's move is returned.
- AlphaBetaSearch gains bestMoveWithTimeSharedTt: the coordinator clears
the shared TT once before launching workers, so helpers must not clear.
- EvaluationNNUE.freshEvaluator builds independent evaluators sharing the
immutable weights (one per thread); the singleton still backs the
default single-instance path.
- NNUEBot uses ParallelSearch with NNUE_SEARCH_THREADS (default 1).
numThreads <= 1 takes the single-worker clearing path, identical to the
previous sequential search. Strength can be validated by self-play
(threads N vs 1) before promoting the default.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>