X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=dbb23b8b067fea0e44e4a1188b4db7c905ae5608;hp=723b701a0a1c8da991d8c7221835815de67f7e62;hb=2142be7d7f2747a3e980a77102ecb29c989fe1ac;hpb=9d4abbc6ebb78c30d80cf699945e355645492b30 diff --git a/src/search.cpp b/src/search.cpp index 723b701a..dbb23b8b 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -72,7 +72,6 @@ namespace { void set_active_threads(int newActiveThreads) { ActiveThreads = newActiveThreads; } void incrementNodeCounter(int threadID) { threads[threadID].nodes++; } void incrementBetaCounter(Color us, Depth d, int threadID) { threads[threadID].betaCutOffs[us] += unsigned(d); } - void print_current_line(SearchStack ss[], int ply, int threadID); void resetNodeCounters(); void resetBetaCounters(); @@ -88,14 +87,14 @@ namespace { Depth depth, int* moves, MovePicker* mp, int master, bool pvNode); private: - friend void poll(); + friend void poll(SearchStack ss[], int ply); int ActiveThreads; volatile bool AllThreadsShouldExit, AllThreadsShouldSleep; Thread threads[MAX_THREADS]; SplitPoint SplitPointStack[MAX_THREADS][ACTIVE_SPLIT_POINTS_MAX]; - Lock MPLock, IOLock; + Lock MPLock; #if !defined(_MSC_VER) pthread_cond_t WaitCond; @@ -159,7 +158,12 @@ namespace { }; - /// Constants + /// Adjustments + + // Step 6. Razoring + + const Depth RazorDepth = 4 * OnePly; + inline Value razor_margin(Depth d) { return Value(0x200 + 0x10 * d); } // Search depth at iteration 1 const Depth InitialDepth = OnePly; @@ -185,9 +189,6 @@ namespace { // remaining ones we will extend it. const Value SingleReplyMargin = Value(0x20); - // Depth limit for razoring - const Depth RazorDepth = 4 * OnePly; - /// Lookup tables initialized at startup // Reduction lookup tables and their getter functions @@ -288,7 +289,7 @@ namespace { int current_search_time(); int nps(); - void poll(); + void poll(SearchStack ss[], int ply); void ponderhit(); void wait_for_stop_or_ponderhit(); void init_ss_array(SearchStack ss[]); @@ -1040,14 +1041,16 @@ namespace { assert(threadID >= 0 && threadID < TM.active_threads()); Move movesSearched[256]; + EvalInfo ei; StateInfo st; const TTEntry* tte; Move ttMove, move; Depth ext, newDepth; - Value oldAlpha, value; - bool isCheck, mateThreat, singleEvasion, moveIsCheck, captureOrPromotion, dangerous; + Value bestValue, value, oldAlpha; + bool isCheck, singleEvasion, moveIsCheck, captureOrPromotion, dangerous; + bool mateThreat = false; int moveCount = 0; - Value bestValue = value = -VALUE_INFINITE; + bestValue = value = -VALUE_INFINITE; if (depth < OnePly) return qsearch(pos, ss, alpha, beta, Depth(0), ply, threadID); @@ -1086,7 +1089,6 @@ namespace { isCheck = pos.is_check(); if (!isCheck) { - EvalInfo ei; ss[ply].eval = evaluate(pos, ei, threadID); update_gains(pos, ss[ply - 1].currentMove, ss[ply - 1].eval, ss[ply].eval); } @@ -1332,15 +1334,15 @@ namespace { if ( !value_is_mate(beta) && !isCheck && depth < RazorDepth - && refinedValue < beta - (0x200 + 16 * depth) + && refinedValue < beta - razor_margin(depth) && ss[ply - 1].currentMove != MOVE_NULL && ttMove == MOVE_NONE && !pos.has_pawn_on_7th(pos.side_to_move())) { - Value rbeta = beta - (0x200 + 16 * depth); + Value rbeta = beta - razor_margin(depth); Value v = qsearch(pos, ss, rbeta-1, rbeta, Depth(0), ply, threadID); if (v < rbeta) - return v; //FIXME: Logically should be: return (v + 0x200 + 16 * depth); + return v; //FIXME: Logically should be: return (v + razor_margin(depth)); } // Step 7. Static null move pruning @@ -1779,20 +1781,25 @@ namespace { // splitting, we don't have to repeat all this work in sp_search(). We // also don't need to store anything to the hash table here: This is taken // care of after we return from the split point. + // FIXME: We are currently ignoring mateThreat flag here void sp_search(SplitPoint* sp, int threadID) { assert(threadID >= 0 && threadID < TM.active_threads()); assert(TM.active_threads() > 1); - Position pos(*sp->pos); - CheckInfo ci(pos); - SearchStack* ss = sp->sstack[threadID]; StateInfo st; - Value value = -VALUE_INFINITE; Move move; + Depth ext, newDepth; + Value value, futilityValueScaled; + bool isCheck, moveIsCheck, captureOrPromotion, dangerous; int moveCount; - bool isCheck = pos.is_check(); + value = -VALUE_INFINITE; + + Position pos(*sp->pos); + CheckInfo ci(pos); + SearchStack* ss = sp->sstack[threadID]; + isCheck = pos.is_check(); // Step 10. Loop through moves // Loop through all legal moves until no moves remain or a beta cutoff occurs @@ -1807,13 +1814,12 @@ namespace { assert(move_is_ok(move)); - bool moveIsCheck = pos.move_is_check(move, ci); - bool captureOrPromotion = pos.move_is_capture_or_promotion(move); + moveIsCheck = pos.move_is_check(move, ci); + captureOrPromotion = pos.move_is_capture_or_promotion(move); // Step 11. Decide the new search depth - bool dangerous; - Depth ext = extension(pos, move, false, captureOrPromotion, moveIsCheck, false, false, &dangerous); - Depth newDepth = sp->depth - OnePly + ext; + ext = extension(pos, move, false, captureOrPromotion, moveIsCheck, false, false, &dangerous); + newDepth = sp->depth - OnePly + ext; // Update current move ss[sp->ply].currentMove = move; @@ -1835,7 +1841,7 @@ namespace { // Value based pruning Depth predictedDepth = newDepth - nonpv_reduction(sp->depth, moveCount); - Value futilityValueScaled = ss[sp->ply].eval + futility_margin(predictedDepth, moveCount) + futilityValueScaled = ss[sp->ply].eval + futility_margin(predictedDepth, moveCount) + H.gain(pos.piece_on(move_from(move)), move_to(move)) + 45; if (futilityValueScaled < sp->beta) @@ -1910,19 +1916,24 @@ namespace { // don't have to repeat all this work in sp_search_pv(). We also don't // need to store anything to the hash table here: This is taken care of // after we return from the split point. + // FIXME: We are ignoring mateThreat flag! void sp_search_pv(SplitPoint* sp, int threadID) { assert(threadID >= 0 && threadID < TM.active_threads()); assert(TM.active_threads() > 1); + StateInfo st; + Move move; + Depth ext, newDepth; + Value value; + bool moveIsCheck, captureOrPromotion, dangerous; + int moveCount; + value = -VALUE_INFINITE; + Position pos(*sp->pos); CheckInfo ci(pos); SearchStack* ss = sp->sstack[threadID]; - StateInfo st; - Value value = -VALUE_INFINITE; - int moveCount; - Move move; // Step 10. Loop through moves // Loop through all legal moves until no moves remain or a beta cutoff occurs @@ -1937,13 +1948,12 @@ namespace { assert(move_is_ok(move)); - bool moveIsCheck = pos.move_is_check(move, ci); - bool captureOrPromotion = pos.move_is_capture_or_promotion(move); + moveIsCheck = pos.move_is_check(move, ci); + captureOrPromotion = pos.move_is_capture_or_promotion(move); // Step 11. Decide the new search depth - bool dangerous; - Depth ext = extension(pos, move, true, captureOrPromotion, moveIsCheck, false, false, &dangerous); - Depth newDepth = sp->depth - OnePly + ext; + ext = extension(pos, move, true, captureOrPromotion, moveIsCheck, false, false, &dangerous); + newDepth = sp->depth - OnePly + ext; // Update current move ss[sp->ply].currentMove = move; @@ -2041,13 +2051,12 @@ namespace { NodesSincePoll++; if (NodesSincePoll >= NodesBetweenPolls) { - poll(); + poll(ss, ply); NodesSincePoll = 0; } } ss[ply].init(ply); ss[ply + 2].initKillers(); - TM.print_current_line(ss, ply, threadID); } @@ -2405,7 +2414,7 @@ namespace { // looks at the time consumed so far and decides if it's time to abort the // search. - void poll() { + void poll(SearchStack ss[], int ply) { static int lastInfoTime; int t = current_search_time(); @@ -2447,7 +2456,6 @@ namespace { else if (t - lastInfoTime >= 1000) { lastInfoTime = t; - lock_grab(&TM.IOLock); if (dbg_show_mean) dbg_print_mean(); @@ -2458,10 +2466,15 @@ namespace { cout << "info nodes " << TM.nodes_searched() << " nps " << nps() << " time " << t << " hashfull " << TT.full() << endl; - lock_release(&TM.IOLock); + // We only support current line printing in single thread mode + if (ShowCurrentLine && TM.active_threads() == 1) + { + cout << "info currline"; + for (int p = 0; p < ply; p++) + cout << " " << ss[p].currentMove; - if (ShowCurrentLine) - TM.threads[0].printCurrentLineRequest = true; + cout << endl; + } } // Should we stop the search? @@ -2690,7 +2703,6 @@ namespace { // Initialize global locks lock_init(&MPLock, NULL); - lock_init(&IOLock, NULL); // Initialize SplitPointStack locks for (i = 0; i < MAX_THREADS; i++) @@ -2992,47 +3004,8 @@ namespace { // This makes the threads to go to sleep AllThreadsShouldSleep = true; - - // Reset flags to a known state. - for (int i = 1; i < ActiveThreads; i++) - { - // This flag can be in a random state - threads[i].printCurrentLineRequest = false; - } - } - - // print_current_line() prints _once_ the current line of search for a - // given thread and then setup the print request for the next thread. - // Called when the UCI option UCI_ShowCurrLine is 'true'. - - void ThreadsManager::print_current_line(SearchStack ss[], int ply, int threadID) { - - assert(ply >= 0 && ply < PLY_MAX); - assert(threadID >= 0 && threadID < ActiveThreads); - - if (!threads[threadID].printCurrentLineRequest) - return; - - // One shot only - threads[threadID].printCurrentLineRequest = false; - - if (threads[threadID].state == THREAD_SEARCHING) - { - lock_grab(&IOLock); - cout << "info currline " << (threadID + 1); - for (int p = 0; p < ply; p++) - cout << " " << ss[p].currentMove; - - cout << endl; - lock_release(&IOLock); - } - - // Setup print request for the next thread ID - if (threadID + 1 < ActiveThreads) - threads[threadID + 1].printCurrentLineRequest = true; } - /// The RootMoveList class // RootMoveList c'tor