X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=f205774124063dca9e3fed76471d2e0083d89115;hp=2c4d5ece2eb237f861890d7ac4add6c1c8c273ed;hb=56e09b4cc82c1cda42815482967670499fc64b61;hpb=a1b8c8109b464abd9d026b1ef740f1bace814b29 diff --git a/src/search.cpp b/src/search.cpp index 2c4d5ece..f2057741 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -193,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; @@ -426,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"); @@ -447,6 +442,10 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, { ActiveThreads = newActiveThreads; init_eval(ActiveThreads); + // HACK: init_eval() destroys the static castleRightsMask[] array in the + // Position class. The below line repairs the damage. + Position p(pos.to_fen()); + assert(pos.is_ok()); } // Wake up sleeping threads @@ -560,13 +559,14 @@ bool think(const Position& pos, bool infinite, bool ponder, int side_to_move, void init_threads() { volatile int i; + bool ok; #if !defined(_MSC_VER) pthread_t pthread[1]; #endif // Init our logarithmic lookup table - for (int i = 0; i < 512; i++) + for (i = 0; i < 512; i++) lnArray[i] = log(double(i)); // log() returns base-e logarithm for (i = 0; i < THREAD_MAX; i++) @@ -599,12 +599,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); } @@ -835,7 +841,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 @@ -1692,10 +1698,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; @@ -2010,7 +2020,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; } } @@ -2028,11 +2045,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++) @@ -2041,6 +2054,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 @@ -2784,6 +2803,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); @@ -2965,15 +2986,15 @@ namespace { for (i = 0; i < ActiveThreads; i++) splitPoint->slaves[i] = 0; - // Copy the current search stack to the master thread - memcpy(splitPoint->sstack[master], sstck, (ply+1) * sizeof(SearchStack)); + // Copy the tail of current search stack to the master thread + memcpy(splitPoint->sstack[master] + ply - 1, sstck + ply - 1, 3 * sizeof(SearchStack)); Threads[master].splitPoint = splitPoint; // Make copies of the current position and search stack for each thread for (i = 0; i < ActiveThreads && splitPoint->cpus < MaxThreadsPerSplitPoint; i++) if (thread_is_available(i, master)) { - memcpy(splitPoint->sstack[i], sstck, (ply+1) * sizeof(SearchStack)); + memcpy(splitPoint->sstack[i] + ply - 1, sstck + ply - 1, 3 * sizeof(SearchStack)); Threads[i].splitPoint = splitPoint; splitPoint->slaves[i] = 1; splitPoint->cpus++;