X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=902049c351205e8f32405f999f978d8c21ef35e1;hp=30299ac435e68c1305f8708914cc79cbd86c9dd7;hb=8bf9dc825420bddb6d8425352e53a97a285027ec;hpb=79e50a2fbfdf2e866255e002b7d7cdc55d96bb9e diff --git a/src/search.cpp b/src/search.cpp index 30299ac4..902049c3 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -81,7 +81,6 @@ namespace { template void split(Position& pos, SearchStack* ss, Value* alpha, const Value beta, Value* bestValue, Depth depth, Move threatMove, int moveCount, MovePicker* mp, bool pvNode); - private: Lock mpLock; Depth minimumSplitDepth; @@ -234,7 +233,7 @@ namespace { int MultiPV, UCIMultiPV; // Time management variables - int SearchStartTime, MaxNodes, MaxDepth, ExactMaxTime; + int MaxNodes, MaxDepth, ExactMaxTime; bool UseTimeManagement, InfiniteSearch, Pondering, StopOnPonderhit; bool FirstRootMove, StopRequest, QuitRequest, AspirationFailLow; TimeManager TimeMgr; @@ -292,7 +291,7 @@ namespace { void update_gains(const Position& pos, Move move, Value before, Value after); void do_skill_level(Move* best, Move* ponder); - int current_search_time(); + int current_search_time(int set = 0); std::string value_to_uci(Value v); std::string speed_to_uci(int64_t nodes); void poll(const Position& pos); @@ -449,7 +448,7 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[ // Initialize global search-related variables StopOnPonderhit = StopRequest = QuitRequest = AspirationFailLow = SendSearchedNodes = false; NodesSincePoll = 0; - SearchStartTime = get_system_time(); + current_search_time(get_system_time()); ExactMaxTime = maxTime; MaxDepth = maxDepth; MaxNodes = maxNodes; @@ -1844,9 +1843,14 @@ split_point_start: // At split points actual search starts from here // current_search_time() returns the number of milliseconds which have passed // since the beginning of the current search. - int current_search_time() { + int current_search_time(int set) { + + static int searchStartTime; - return get_system_time() - SearchStartTime; + if (set) + searchStartTime = set; + + return get_system_time() - searchStartTime; } @@ -1862,9 +1866,9 @@ split_point_start: // At split points actual search starts from here std::stringstream s; if (abs(v) < VALUE_MATE - PLY_MAX * ONE_PLY) - s << "cp " << int(v) * 100 / int(PawnValueMidgame); // Scale to centipawns + s << "cp " << int(v) * 100 / int(PawnValueMidgame); // Scale to centipawns else - s << "mate " << (v > 0 ? VALUE_MATE - v + 1 : -VALUE_MATE - v) / 2; + s << "mate " << (v > 0 ? VALUE_MATE - v + 1 : -VALUE_MATE - v) / 2; return s.str(); } @@ -2034,7 +2038,7 @@ split_point_start: // At split points actual search starts from here assert(threadID >= 0 && threadID < MAX_THREADS); int i; - bool allFinished = false; + bool allFinished; while (true) { @@ -2049,7 +2053,8 @@ split_point_start: // At split points actual search starts from here // If we are not thinking, wait for a condition to be signaled // instead of wasting CPU time polling for work. - while ( threadID >= activeThreads || threads[threadID].state == THREAD_INITIALIZING + while ( threadID >= activeThreads + || threads[threadID].state == THREAD_INITIALIZING || (useSleepingThreads && threads[threadID].state == THREAD_AVAILABLE)) { assert(!sp || useSleepingThreads); @@ -2058,7 +2063,7 @@ split_point_start: // At split points actual search starts from here if (threads[threadID].state == THREAD_INITIALIZING) threads[threadID].state = THREAD_AVAILABLE; - // Grab the lock to avoid races with wake_sleeping_thread() + // Grab the lock to avoid races with Thread::wake_up() lock_grab(&threads[threadID].sleepLock); // If we are master and all slaves have finished do not go to sleep @@ -2085,7 +2090,7 @@ split_point_start: // At split points actual search starts from here threads[threadID].state = THREAD_SEARCHING; - // Copy SplitPoint position and search stack and call search() + // Copy split point position and search stack and call search() // with SplitPoint template parameter set to true. SearchStack ss[PLY_MAX_PLUS_2]; SplitPoint* tsp = threads[threadID].splitPoint; @@ -2105,7 +2110,9 @@ split_point_start: // At split points actual search starts from here // Wake up master thread so to allow it to return from the idle loop in // case we are the last slave of the split point. - if (useSleepingThreads && threadID != tsp->master && threads[tsp->master].state == THREAD_AVAILABLE) + if ( useSleepingThreads + && threadID != tsp->master + && threads[tsp->master].state == THREAD_AVAILABLE) threads[tsp->master].wake_up(); } @@ -2132,41 +2139,36 @@ split_point_start: // At split points actual search starts from here } - // init_threads() is called during startup. It launches all helper threads, - // and initializes the split point stack and the global locks and condition - // objects. + // init_threads() is called during startup. Initializes locks and condition + // variables and launches all threads sending them immediately to sleep. void ThreadsManager::init_threads() { int i, arg[MAX_THREADS]; bool ok; - // Initialize global locks + // This flag is needed to properly end the threads when program exits + allThreadsShouldExit = false; + + // Threads will sent to sleep as soon as created, only main thread is kept alive + activeThreads = 1; + lock_init(&mpLock); for (i = 0; i < MAX_THREADS; i++) { + // Initialize thread and split point locks lock_init(&threads[i].sleepLock); cond_init(&threads[i].sleepCond); - } - // Initialize splitPoints[] locks - for (i = 0; i < MAX_THREADS; i++) for (int j = 0; j < MAX_ACTIVE_SPLIT_POINTS; j++) lock_init(&(threads[i].splitPoints[j].lock)); - // Will be set just before program exits to properly end the threads - allThreadsShouldExit = false; - - // Threads will be put all threads to sleep as soon as created - activeThreads = 1; - - // All threads except the main thread should be initialized to THREAD_INITIALIZING - threads[0].state = THREAD_SEARCHING; - for (i = 1; i < MAX_THREADS; i++) - threads[i].state = THREAD_INITIALIZING; + // All threads but first should be set to THREAD_INITIALIZING + threads[i].state = (i == 0 ? THREAD_SEARCHING : THREAD_INITIALIZING); + } - // Launch the helper threads + // Create and startup the threads for (i = 1; i < MAX_THREADS; i++) { arg[i] = i; @@ -2195,28 +2197,27 @@ split_point_start: // At split points actual search starts from here void ThreadsManager::exit_threads() { - allThreadsShouldExit = true; // Let the woken up threads to exit idle_loop() + // Force the woken up threads to exit idle_loop() and hence terminate + allThreadsShouldExit = true; - // Wake up all the threads and waits for termination - for (int i = 1; i < MAX_THREADS; i++) + for (int i = 0; i < MAX_THREADS; i++) { - threads[i].wake_up(); - while (threads[i].state != THREAD_TERMINATED) {} - } + // Wake up all the threads and waits for termination + if (i != 0) + { + threads[i].wake_up(); + while (threads[i].state != THREAD_TERMINATED) {} + } + + // Now we can safely destroy the locks and wait conditions + lock_destroy(&threads[i].sleepLock); + cond_destroy(&threads[i].sleepCond); - // Now we can safely destroy the locks - for (int i = 0; i < MAX_THREADS; i++) for (int j = 0; j < MAX_ACTIVE_SPLIT_POINTS; j++) lock_destroy(&(threads[i].splitPoints[j].lock)); + } lock_destroy(&mpLock); - - // Now we can safely destroy the wait conditions - for (int i = 0; i < MAX_THREADS; i++) - { - lock_destroy(&threads[i].sleepLock); - cond_destroy(&threads[i].sleepCond); - } }