Files
Stockfish/src/thread.h
Michael Chaly b4d995d0d9 Introduce static evaluation correction history
Idea from Caissa (https://github.com/Witek902/Caissa) chess engine.

With given pawn structure collect data with how often search result and by how
much it was better / worse than static evalution of position and use it to
adjust static evaluation of positions with given pawn structure. Details:

1. excludes positions with fail highs and moves producing it being a capture;
2. update value is function of not only difference between best value and static
   evaluation but also is multiplied by linear function of depth;
3. maximum update value is maximum value of correction history divided by 2;
4. correction history itself is divided by 32 when applied so maximum value of
   static evaluation adjustment is 32 internal units.

Passed STC:
https://tests.stockfishchess.org/tests/view/658fc7b679aa8af82b955cac
LLR: 2.96 (-2.94,2.94) <0.00,2.00>
Total: 128672 W: 32757 L: 32299 D: 63616
Ptnml(0-2): 441, 15241, 32543, 15641, 470

Passed LTC:
https://tests.stockfishchess.org/tests/view/65903f6979aa8af82b9566f1
LLR: 2.95 (-2.94,2.94) <0.50,2.50>
Total: 97422 W: 24626 L: 24178 D: 48618
Ptnml(0-2): 41, 10837, 26527, 11245, 61

closes https://github.com/official-stockfish/Stockfish/pull/4950

Bench: 1157852
2023-12-31 20:00:06 +01:00

137 lines
4.2 KiB
C++

/*
Stockfish, a UCI chess playing engine derived from Glaurung 2.1
Copyright (C) 2004-2023 The Stockfish developers (see AUTHORS file)
Stockfish is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
Stockfish is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef THREAD_H_INCLUDED
#define THREAD_H_INCLUDED
#include <atomic>
#include <condition_variable>
#include <cstddef>
#include <cstdint>
#include <mutex>
#include <vector>
#include "movepick.h"
#include "position.h"
#include "search.h"
#include "thread_win32_osx.h"
#include "types.h"
namespace Stockfish {
// Thread class keeps together all the thread-related stuff.
class Thread {
std::mutex mutex;
std::condition_variable cv;
size_t idx;
bool exit = false, searching = true; // Set before starting std::thread
NativeThread stdThread;
public:
explicit Thread(size_t);
virtual ~Thread();
virtual void search();
void clear();
void idle_loop();
void start_searching();
void wait_for_search_finished();
size_t id() const { return idx; }
size_t pvIdx, pvLast;
std::atomic<uint64_t> nodes, tbHits, bestMoveChanges;
int selDepth, nmpMinPly;
Value bestValue, optimism[COLOR_NB];
Position rootPos;
StateInfo rootState;
Search::RootMoves rootMoves;
Depth rootDepth, completedDepth;
Value rootDelta;
Value rootSimpleEval;
CounterMoveHistory counterMoves;
ButterflyHistory mainHistory;
CapturePieceToHistory captureHistory;
ContinuationHistory continuationHistory[2][2];
PawnHistory pawnHistory;
CorrectionHistory correctionHistory;
};
// MainThread is a derived class specific for main thread
struct MainThread: public Thread {
using Thread::Thread;
void search() override;
void check_time();
double previousTimeReduction;
Value bestPreviousScore;
Value bestPreviousAverageScore;
Value iterValue[4];
int callsCnt;
bool stopOnPonderhit;
std::atomic_bool ponder;
};
// ThreadPool struct handles all the threads-related stuff like init, starting,
// parking and, most importantly, launching a thread. All the access to threads
// is done through this class.
struct ThreadPool {
void start_thinking(Position&, StateListPtr&, const Search::LimitsType&, bool = false);
void clear();
void set(size_t);
MainThread* main() const { return static_cast<MainThread*>(threads.front()); }
uint64_t nodes_searched() const { return accumulate(&Thread::nodes); }
uint64_t tb_hits() const { return accumulate(&Thread::tbHits); }
Thread* get_best_thread() const;
void start_searching();
void wait_for_search_finished() const;
std::atomic_bool stop, increaseDepth;
auto cbegin() const noexcept { return threads.cbegin(); }
auto begin() noexcept { return threads.begin(); }
auto end() noexcept { return threads.end(); }
auto cend() const noexcept { return threads.cend(); }
auto size() const noexcept { return threads.size(); }
auto empty() const noexcept { return threads.empty(); }
private:
StateListPtr setupStates;
std::vector<Thread*> threads;
uint64_t accumulate(std::atomic<uint64_t> Thread::*member) const {
uint64_t sum = 0;
for (Thread* th : threads)
sum += (th->*member).load(std::memory_order_relaxed);
return sum;
}
};
extern ThreadPool Threads;
} // namespace Stockfish
#endif // #ifndef THREAD_H_INCLUDED