1
0
Fork 0
mirror of https://github.com/sockspls/badfish synced 2025-07-11 19:49:14 +00:00

Revert thread_local stuff

Unfortunatly accessing thread local variable
is much slower than object data (see previous
patch log msg), so we have to revert to old code
to avoid speed regression.

No functional change.

Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
Marco Costalba 2012-04-06 18:36:46 +01:00
parent b1f57e92ce
commit c2fc80e5d1
10 changed files with 42 additions and 40 deletions

View file

@ -107,7 +107,7 @@ void benchmark(istringstream& is) {
for (size_t i = 0; i < fens.size(); i++) for (size_t i = 0; i < fens.size(); i++)
{ {
Position pos(fens[i], false); Position pos(fens[i], false, NULL);
cerr << "\nPosition: " << i + 1 << '/' << fens.size() << endl; cerr << "\nPosition: " << i + 1 << '/' << fens.size() << endl;

View file

@ -77,7 +77,7 @@ namespace {
string fen = sides[0] + char('0' + int(8 - code.length())) string fen = sides[0] + char('0' + int(8 - code.length()))
+ sides[1] + "/8/8/8/8/8/8/8 w - - 0 10"; + sides[1] + "/8/8/8/8/8/8/8 w - - 0 10";
return Position(fen, false).material_key(); return Position(fen, false, NULL).material_key();
} }
template<typename M> template<typename M>

View file

@ -371,7 +371,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
margins[WHITE] = margins[BLACK] = VALUE_ZERO; margins[WHITE] = margins[BLACK] = VALUE_ZERO;
// Probe the material hash table // Probe the material hash table
ei.mi = this_thread->materialTable.probe(pos); ei.mi = pos.this_thread()->materialTable.probe(pos);
score += ei.mi->material_value(); score += ei.mi->material_value();
// If we have a specialized evaluation function for the current material // If we have a specialized evaluation function for the current material
@ -383,7 +383,7 @@ Value do_evaluate(const Position& pos, Value& margin) {
} }
// Probe the pawn hash table // Probe the pawn hash table
ei.pi = this_thread->pawnTable.probe(pos); ei.pi = pos.this_thread()->pawnTable.probe(pos);
score += ei.pi->pawns_value(); score += ei.pi->pawns_value();
// Initialize attack and king safety bitboards // Initialize attack and king safety bitboards

View file

@ -92,17 +92,19 @@ CheckInfo::CheckInfo(const Position& pos) {
} }
/// Position::operator=() creates a copy of 'pos'. We want the new born Position /// Position::copy() creates a copy of 'pos'. We want the new born Position
/// object do not depend on any external data so we detach state pointer from /// object do not depend on any external data so we detach state pointer from
/// the source one. /// the source one.
Position& Position::operator=(const Position& pos) { void Position::copy(const Position& pos, Thread* th) {
memcpy(this, &pos, sizeof(Position)); memcpy(this, &pos, sizeof(Position));
startState = *st; startState = *st;
st = &startState; st = &startState;
thisThread = th;
nodes = 0; nodes = 0;
return *this;
assert(pos_is_ok());
} }
@ -110,7 +112,7 @@ Position& Position::operator=(const Position& pos) {
/// string. This function is not very robust - make sure that input FENs are /// string. This function is not very robust - make sure that input FENs are
/// correct (this is assumed to be the responsibility of the GUI). /// correct (this is assumed to be the responsibility of the GUI).
void Position::from_fen(const string& fenStr, bool isChess960) { void Position::from_fen(const string& fenStr, bool isChess960, Thread* th) {
/* /*
A FEN string defines a particular position using only the ASCII character set. A FEN string defines a particular position using only the ASCII character set.
@ -226,6 +228,7 @@ void Position::from_fen(const string& fenStr, bool isChess960) {
st->npMaterial[BLACK] = compute_non_pawn_material(BLACK); st->npMaterial[BLACK] = compute_non_pawn_material(BLACK);
st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove); st->checkersBB = attackers_to(king_square(sideToMove)) & pieces(~sideToMove);
chess960 = isChess960; chess960 = isChess960;
thisThread = th;
assert(pos_is_ok()); assert(pos_is_ok());
} }
@ -328,7 +331,7 @@ void Position::print(Move move) const {
if (move) if (move)
{ {
Position p(*this); Position p(*this, thisThread);
cout << "\nMove is: " << (sideToMove == BLACK ? ".." : "") << move_to_san(p, move); cout << "\nMove is: " << (sideToMove == BLACK ? ".." : "") << move_to_san(p, move);
} }
@ -895,8 +898,8 @@ void Position::do_move(Move m, StateInfo& newSt, const CheckInfo& ci, bool moveI
} }
// Prefetch pawn and material hash tables // Prefetch pawn and material hash tables
prefetch((char*)this_thread->pawnTable.entries[st->pawnKey]); prefetch((char*)thisThread->pawnTable.entries[st->pawnKey]);
prefetch((char*)this_thread->materialTable.entries[st->materialKey]); prefetch((char*)thisThread->materialTable.entries[st->materialKey]);
// Update incremental scores // Update incremental scores
st->psqScore += psq_delta(piece, from, to); st->psqScore += psq_delta(piece, from, to);
@ -1538,9 +1541,10 @@ void Position::init() {
void Position::flip() { void Position::flip() {
// Make a copy of current position before to start changing // Make a copy of current position before to start changing
const Position pos(*this); const Position pos(*this, thisThread);
clear(); clear();
thisThread = pos.this_thread();
// Board // Board
for (Square s = SQ_A1; s <= SQ_H8; s++) for (Square s = SQ_A1; s <= SQ_H8; s++)

View file

@ -84,14 +84,19 @@ struct StateInfo {
/// * A counter for detecting 50 move rule draws. /// * A counter for detecting 50 move rule draws.
class Position { class Position {
public:
Position() {} // No copy c'tor or assignment operator allowed
Position(const Position& p) { *this = p; } Position(const Position&);
Position(const std::string& f, bool c960) { from_fen(f, c960); }
Position& operator=(const Position&); Position& operator=(const Position&);
public:
Position() {}
Position(const Position& p, Thread* t) { copy(p, t); }
Position(const std::string& f, bool c960, Thread* t) { from_fen(f, c960, t); }
// Text input/output // Text input/output
void from_fen(const std::string& fen, bool isChess960); void copy(const Position& pos, Thread* th);
void from_fen(const std::string& fen, bool isChess960, Thread* th);
const std::string to_fen() const; const std::string to_fen() const;
void print(Move m = MOVE_NONE) const; void print(Move m = MOVE_NONE) const;
@ -171,6 +176,7 @@ public:
Color side_to_move() const; Color side_to_move() const;
int startpos_ply_counter() const; int startpos_ply_counter() const;
bool is_chess960() const; bool is_chess960() const;
Thread* this_thread() const;
int64_t nodes_searched() const; int64_t nodes_searched() const;
void set_nodes_searched(int64_t n); void set_nodes_searched(int64_t n);
template<bool SkipRepetition> bool is_draw() const; template<bool SkipRepetition> bool is_draw() const;
@ -218,6 +224,7 @@ private:
int64_t nodes; int64_t nodes;
int startPosPly; int startPosPly;
Color sideToMove; Color sideToMove;
Thread* thisThread;
StateInfo* st; StateInfo* st;
int chess960; int chess960;
@ -427,4 +434,8 @@ inline PieceType Position::captured_piece_type() const {
return st->capturedType; return st->capturedType;
} }
inline Thread* Position::this_thread() const {
return thisThread;
}
#endif // !defined(POSITION_H_INCLUDED) #endif // !defined(POSITION_H_INCLUDED)

View file

@ -332,7 +332,7 @@ finalize:
// but if we are pondering or in infinite search, we shouldn't print the best // but if we are pondering or in infinite search, we shouldn't print the best
// move before we are told to do so. // move before we are told to do so.
if (!Signals.stop && (Limits.ponder || Limits.infinite)) if (!Signals.stop && (Limits.ponder || Limits.infinite))
this_thread->wait_for_stop_or_ponderhit(); pos.this_thread()->wait_for_stop_or_ponderhit();
// Best move could be MOVE_NONE when searching on a stalemate position // Best move could be MOVE_NONE when searching on a stalemate position
cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960) cout << "bestmove " << move_to_uci(RootMoves[0].pv[0], Chess960)
@ -543,7 +543,7 @@ namespace {
bool isPvMove, inCheck, singularExtensionNode, givesCheck; bool isPvMove, inCheck, singularExtensionNode, givesCheck;
bool captureOrPromotion, dangerous, doFullDepthSearch; bool captureOrPromotion, dangerous, doFullDepthSearch;
int moveCount = 0, playedMoveCount = 0; int moveCount = 0, playedMoveCount = 0;
Thread* thisThread = this_thread; Thread* thisThread = pos.this_thread();
SplitPoint* sp = NULL; SplitPoint* sp = NULL;
refinedValue = bestValue = value = -VALUE_INFINITE; refinedValue = bestValue = value = -VALUE_INFINITE;
@ -1825,7 +1825,7 @@ void Thread::idle_loop(SplitPoint* sp_master) {
lock_release(Threads.splitLock); lock_release(Threads.splitLock);
Stack ss[MAX_PLY_PLUS_2]; Stack ss[MAX_PLY_PLUS_2];
Position pos(*sp->pos); Position pos(*sp->pos, this);
memcpy(ss, sp->ss - 1, 4 * sizeof(Stack)); memcpy(ss, sp->ss - 1, 4 * sizeof(Stack));
(ss+1)->sp = sp; (ss+1)->sp = sp;

View file

@ -28,22 +28,17 @@
using namespace Search; using namespace Search;
ThreadsManager Threads; // Global object ThreadsManager Threads; // Global object
THREAD_LOCAL Thread* this_thread; // Thread local variable
namespace { extern "C" { namespace { extern "C" {
// start_routine() is the C function which is called when a new thread // start_routine() is the C function which is called when a new thread
// is launched. It is a wrapper to member function pointed by start_fn. // is launched. It is a wrapper to member function pointed by start_fn.
long start_routine(Thread* th) { long start_routine(Thread* th) { (th->*(th->start_fn))(); return 0; }
this_thread = th; // Save pointer into thread local storage
(th->*(th->start_fn))();
return 0;
}
} } } }
// Thread c'tor starts a newly-created thread of execution that will call // Thread c'tor starts a newly-created thread of execution that will call
// the idle loop function pointed by start_fn going immediately to sleep. // the idle loop function pointed by start_fn going immediately to sleep.
@ -210,7 +205,6 @@ void ThreadsManager::init() {
lock_init(splitLock); lock_init(splitLock);
timer = new Thread(&Thread::timer_loop); timer = new Thread(&Thread::timer_loop);
threads.push_back(new Thread(&Thread::main_loop)); threads.push_back(new Thread(&Thread::main_loop));
this_thread = main_thread(); // Use main thread's resources
read_uci_options(); read_uci_options();
} }
@ -313,7 +307,7 @@ Value ThreadsManager::split(Position& pos, Stack* ss, Value alpha, Value beta,
assert(beta <= VALUE_INFINITE); assert(beta <= VALUE_INFINITE);
assert(depth > DEPTH_ZERO); assert(depth > DEPTH_ZERO);
Thread* master = this_thread; Thread* master = pos.this_thread();
if (master->splitPointsCnt >= MAX_SPLITPOINTS_PER_THREAD) if (master->splitPointsCnt >= MAX_SPLITPOINTS_PER_THREAD)
return bestValue; return bestValue;
@ -440,7 +434,7 @@ void ThreadsManager::start_searching(const Position& pos, const LimitsType& limi
Signals.stopOnPonderhit = Signals.firstRootMove = false; Signals.stopOnPonderhit = Signals.firstRootMove = false;
Signals.stop = Signals.failedLowAtRoot = false; Signals.stop = Signals.failedLowAtRoot = false;
RootPosition = pos; RootPosition.copy(pos, main_thread());
Limits = limits; Limits = limits;
RootMoves.clear(); RootMoves.clear();

View file

@ -119,7 +119,7 @@ public:
bool use_sleeping_threads() const { return useSleepingThreads; } bool use_sleeping_threads() const { return useSleepingThreads; }
int min_split_depth() const { return minimumSplitDepth; } int min_split_depth() const { return minimumSplitDepth; }
int size() const { return (int)threads.size(); } int size() const { return (int)threads.size(); }
Thread* main_thread() const { return threads[0]; } Thread* main_thread() { return threads[0]; }
void wake_up() const; void wake_up() const;
void sleep() const; void sleep() const;
@ -146,6 +146,5 @@ private:
}; };
extern ThreadsManager Threads; extern ThreadsManager Threads;
extern THREAD_LOCAL Thread* this_thread;
#endif // !defined(THREAD_H_INCLUDED) #endif // !defined(THREAD_H_INCLUDED)

View file

@ -64,12 +64,6 @@
# define FORCE_INLINE inline # define FORCE_INLINE inline
#endif #endif
#if defined(__GNUC__)
# define THREAD_LOCAL __thread
#else
# define THREAD_LOCAL __declspec(thread)
#endif
#if defined(USE_POPCNT) #if defined(USE_POPCNT)
const bool HasPopCnt = true; const bool HasPopCnt = true;
#else #else

View file

@ -56,7 +56,7 @@ namespace {
void uci_loop(const string& args) { void uci_loop(const string& args) {
Position pos(StartFEN, false); // The root position Position pos(StartFEN, false, Threads.main_thread()); // The root position
string cmd, token; string cmd, token;
while (token != "quit") while (token != "quit")
@ -167,7 +167,7 @@ namespace {
else else
return; return;
pos.from_fen(fen, Options["UCI_Chess960"]); pos.from_fen(fen, Options["UCI_Chess960"], Threads.main_thread());
// Parse move list (if any) // Parse move list (if any)
while (is >> token && (m = move_from_uci(pos, token)) != MOVE_NONE) while (is >> token && (m = move_from_uci(pos, token)) != MOVE_NONE)