X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=5d2e5175b052bdc35fc5019bdf45dfa39bbd9860;hp=43fb7067a4692a0ca8915c68316215125e109261;hb=5894c759cd20bac8183f8c53cb833eee23e6b4eb;hpb=c01af5676913cbb8a522bd080b6d8559c7450f3a diff --git a/src/search.cpp b/src/search.cpp index 43fb7067..5d2e5175 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -23,6 +23,7 @@ //// #include +#include #include #include #include @@ -192,9 +193,6 @@ namespace { /// Variables initialized by UCI options - // Minimum number of full depth (i.e. non-reduced) moves at PV and non-PV nodes - int LMRPVMoves, LMRNonPVMoves; - // Depth limit for use of dynamic threat detection Depth ThreatDepth; @@ -235,6 +233,10 @@ namespace { bool UseLogFile; std::ofstream LogFile; + // Natural logarithmic lookup table and its getter function + double lnArray[512]; + inline double ln(int i) { return lnArray[i]; } + // MP related variables int ActiveThreads = 1; Depth MinimumSplitDepth; @@ -319,13 +321,6 @@ namespace { //// Functions //// -//FIXME: HACK -static double lnArray[512]; - -inline double ln(int i) -{ - return lnArray[i]; -} /// perft() is our utility to verify move generation is bug free. All the legal /// moves up to given depth are generated and counted and the sum returned. @@ -428,8 +423,6 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, MateThreatExtension[1] = Depth(get_option_value_int("Mate Threat Extension (PV nodes)")); MateThreatExtension[0] = Depth(get_option_value_int("Mate Threat Extension (non-PV nodes)")); - LMRPVMoves = get_option_value_int("Full Depth Moves (PV nodes)") + 1; - LMRNonPVMoves = get_option_value_int("Full Depth Moves (non-PV nodes)") + 1; ThreatDepth = get_option_value_int("Threat Depth") * OnePly; Chess960 = get_option_value_bool("UCI_Chess960"); @@ -559,20 +552,19 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, /// and initializes the split point stack and the global locks and condition /// objects. -#include //FIXME: HACK - void init_threads() { - // FIXME: HACK!! - for (int i = 0; i < 512; i++) - lnArray[i] = log(double(i)); - volatile int i; + bool ok; #if !defined(_MSC_VER) pthread_t pthread[1]; #endif + // Init our logarithmic lookup table + for (i = 0; i < 512; i++) + lnArray[i] = log(double(i)); // log() returns base-e logarithm + for (i = 0; i < THREAD_MAX; i++) Threads[i].activeSplitPoints = 0; @@ -603,12 +595,18 @@ void init_threads() { for (i = 1; i < THREAD_MAX; i++) { #if !defined(_MSC_VER) - pthread_create(pthread, NULL, init_thread, (void*)(&i)); + ok = (pthread_create(pthread, NULL, init_thread, (void*)(&i)) == 0); #else DWORD iID[1]; - CreateThread(NULL, 0, init_thread, (LPVOID)(&i), 0, iID); + ok = (CreateThread(NULL, 0, init_thread, (LPVOID)(&i), 0, iID) != NULL); #endif + if (!ok) + { + cout << "Failed to create thread number " << i << endl; + Application::exit_with_failure(); + } + // Wait until the thread has finished launching while (!Threads[i].running); } @@ -839,7 +837,7 @@ namespace { // If we are pondering or in infinite search, we shouldn't print the // best move before we are told to do so. - if (!AbortSearch && (PonderSearch || InfiniteSearch)) + if (!AbortSearch && !ExactMaxTime && (PonderSearch || InfiniteSearch)) wait_for_stop_or_ponderhit(); else // Print final search statistics @@ -1696,10 +1694,14 @@ namespace { if (bestValue > alpha) alpha = bestValue; + // If we are near beta then try to get a cutoff pushing checks a bit further + bool deepChecks = depth == -OnePly && staticValue >= beta - PawnValueMidgame / 8; + // Initialize a MovePicker object for the current position, and prepare - // to search the moves. Because the depth is <= 0 here, only captures, - // queen promotions and checks (only if depth == 0) will be generated. - MovePicker mp = MovePicker(pos, ttMove, depth, H); + // to search the moves. Because the depth is <= 0 here, only captures, + // queen promotions and checks (only if depth == 0 or depth == -OnePly + // and we are near beta) will be generated. + MovePicker mp = MovePicker(pos, ttMove, deepChecks ? Depth(0) : depth, H); CheckInfo ci(pos); enoughMaterial = pos.non_pawn_material(pos.side_to_move()) > RookValueMidgame; futilityBase = staticValue + FutilityMarginQS + ei.futilityMargin; @@ -2014,7 +2016,14 @@ namespace { if (sp->ply == 1 && RootMoveNumber == 1) Threads[threadID].failHighPly1 = true; - value = -search_pv(pos, ss, -sp->beta, -sp->alpha, newDepth, sp->ply+1, threadID); + // If another thread has failed high then sp->alpha has been increased + // to be higher or equal then beta, if so, avoid to start a PV search. + localAlpha = sp->alpha; + if (localAlpha < sp->beta) + value = -search_pv(pos, ss, -sp->beta, -localAlpha, newDepth, sp->ply+1, threadID); + else + assert(thread_should_stop(threadID)); + Threads[threadID].failHighPly1 = false; } } @@ -2032,11 +2041,7 @@ namespace { sp->bestValue = value; if (value > sp->alpha) { - sp->alpha = value; - sp_update_pv(sp->parentSstack, ss, sp->ply); - if (value == value_mate_in(sp->ply + 1)) - ss[sp->ply].mateKiller = move; - + // Ask threads to stop before to modify sp->alpha if (value >= sp->beta) { for (int i = 0; i < ActiveThreads; i++) @@ -2045,6 +2050,12 @@ namespace { sp->finished = true; } + + sp->alpha = value; + + sp_update_pv(sp->parentSstack, ss, sp->ply); + if (value == value_mate_in(sp->ply + 1)) + ss[sp->ply].mateKiller = move; } // If we are at ply 1, and we are searching the first root move at // ply 0, set the 'Problem' variable if the score has dropped a lot @@ -2788,6 +2799,8 @@ namespace { // If this thread has been assigned work, launch a search if (Threads[threadID].workIsWaiting) { + assert(!Threads[threadID].idle); + Threads[threadID].workIsWaiting = false; if (Threads[threadID].splitPoint->pvNode) sp_search_pv(Threads[threadID].splitPoint, threadID);