X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=f7718ce442d50136b9508405bc6f3bdb76e34654;hp=121575f554525c6a2b13b52140a7d4d6fa2f86b6;hb=55297064268e47103f95a1eb8fd8fe80b6aa2887;hpb=efeb37c33f15a903dbe5706529a7a26511e9ca58 diff --git a/src/search.cpp b/src/search.cpp index 121575f5..f7718ce4 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -94,7 +94,7 @@ namespace { int ActiveThreads; volatile bool AllThreadsShouldExit; Thread threads[MAX_THREADS]; - Lock MPLock; + Lock MPLock, WaitLock; WaitCondition WaitCond[MAX_THREADS]; }; @@ -263,7 +263,6 @@ namespace { // Multi-threads related variables Depth MinimumSplitDepth; int MaxThreadsPerSplitPoint; - bool UseSleepingMaster; ThreadsManager ThreadsMgr; // Node counters, used only by thread[0] but try to keep in different cache @@ -456,7 +455,6 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[ MaxThreadsPerSplitPoint = Options["Maximum Number of Threads per Split Point"].value(); MultiPV = Options["MultiPV"].value(); UseLogFile = Options["Use Search Log"].value(); - UseSleepingMaster = Options["Use Sleeping Master"].value(); if (UseLogFile) LogFile.open(Options["Search Log Filename"].value().c_str(), std::ios::out | std::ios::app); @@ -471,6 +469,10 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[ init_eval(ThreadsMgr.active_threads()); } + // Wake up needed threads + for (int i = 1; i < newActiveThreads; i++) + ThreadsMgr.wake_sleeping_thread(i); + // Set thinking time int myTime = time[pos.side_to_move()]; int myIncrement = increment[pos.side_to_move()]; @@ -503,6 +505,9 @@ bool think(Position& pos, bool infinite, bool ponder, int time[], int increment[ if (UseLogFile) LogFile.close(); + // This makes all the threads to go to sleep + ThreadsMgr.set_active_threads(1); + return !Quit; } @@ -656,7 +661,7 @@ namespace { << " time " << current_search_time() << endl; // Print the best move and the ponder move to the standard output - if (pv[0] == MOVE_NONE) + if (pv[0] == MOVE_NONE || MultiPV > 1) { pv[0] = rml.move(0); pv[1] = MOVE_NONE; @@ -1282,6 +1287,17 @@ split_point_start: // At split points actual search starts from here continue; } + + // Prune neg. see moves at low depths + if ( predictedDepth < 2 * ONE_PLY + && bestValue > value_mated_in(PLY_MAX) + && pos.see_sign(move) < 0) + { + if (SpNode) + lock_grab(&(sp->lock)); + + continue; + } } // Step 13. Make the move @@ -2184,9 +2200,6 @@ split_point_start: // At split points actual search starts from here assert(threadID >= 0 && threadID < MAX_THREADS); - int i; - bool allFinished = false; - while (true) { // Slave threads can exit as soon as AllThreadsShouldExit raises, @@ -2200,31 +2213,22 @@ 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 - || (threads[threadID].state == THREAD_AVAILABLE && (!sp || UseSleepingMaster))) + while (threadID >= ActiveThreads || threads[threadID].state == THREAD_INITIALIZING) { - lock_grab(&MPLock); - - // Test with lock held to avoid races with wake_sleeping_thread() - for (i = 0; sp && i < ActiveThreads && !sp->slaves[i]; i++) {} - allFinished = (i == ActiveThreads); - - // Retest sleep conditions under lock protection - if ( AllThreadsShouldExit - || allFinished - || !( threadID >= ActiveThreads - || threads[threadID].state == THREAD_INITIALIZING - || (threads[threadID].state == THREAD_AVAILABLE && (!sp || UseSleepingMaster)))) - { - lock_release(&MPLock); + assert(!sp); + assert(threadID != 0); + + if (AllThreadsShouldExit) break; - } - // Put thread to sleep threads[threadID].state = THREAD_AVAILABLE; - cond_wait(&WaitCond[threadID], &MPLock); - lock_release(&MPLock); + + lock_grab(&WaitLock); + + if (threadID >= ActiveThreads || threads[threadID].state == THREAD_INITIALIZING) + cond_wait(&WaitCond[threadID], &WaitLock); + + lock_release(&WaitLock); } // If this thread has been assigned work, launch a search @@ -2248,19 +2252,14 @@ split_point_start: // At split points actual search starts from here assert(threads[threadID].state == THREAD_SEARCHING); threads[threadID].state = THREAD_AVAILABLE; - - // 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 (UseSleepingMaster && threadID != tsp->master && threads[tsp->master].state == THREAD_AVAILABLE) - wake_sleeping_thread(tsp->master); } // If this thread is the master of a split point and all slaves have // finished their work at this split point, return from the idle loop. - for (i = 0; sp && i < ActiveThreads && !sp->slaves[i]; i++) {} - allFinished = (i == ActiveThreads); + int i = 0; + for ( ; sp && i < ActiveThreads && !sp->slaves[i]; i++) {} - if (allFinished) + if (i == ActiveThreads) { // Because sp->slaves[] is reset under lock protection, // be sure sp->lock has been released before to return. @@ -2289,6 +2288,7 @@ split_point_start: // At split points actual search starts from here // Initialize global locks lock_init(&MPLock); + lock_init(&WaitLock); for (i = 0; i < MAX_THREADS; i++) cond_init(&WaitCond[i]); @@ -2352,6 +2352,7 @@ split_point_start: // At split points actual search starts from here for (int j = 0; j < MAX_ACTIVE_SPLIT_POINTS; j++) lock_destroy(&(threads[i].splitPoints[j].lock)); + lock_destroy(&WaitLock); lock_destroy(&MPLock); // Now we can safely destroy the wait conditions @@ -2468,7 +2469,6 @@ split_point_start: // At split points actual search starts from here // Initialize the split point object splitPoint.parent = masterThread.splitPoint; - splitPoint.master = master; splitPoint.stopRequest = false; splitPoint.ply = ply; splitPoint.depth = depth; @@ -2518,8 +2518,6 @@ split_point_start: // At split points actual search starts from here assert(i == master || threads[i].state == THREAD_BOOKED); threads[i].state = THREAD_WORKISWAITING; // This makes the slave to exit from idle_loop() - if (i != master) - wake_sleeping_thread(i); } // Everything is set up. The master thread enters the idle loop, from @@ -2548,9 +2546,9 @@ split_point_start: // At split points actual search starts from here void ThreadsManager::wake_sleeping_thread(int threadID) { - lock_grab(&MPLock); + lock_grab(&WaitLock); cond_signal(&WaitCond[threadID]); - lock_release(&MPLock); + lock_release(&WaitLock); }