X-Git-Url: https://git.sesse.net/?p=stockfish;a=blobdiff_plain;f=src%2Fsearch.cpp;h=d54c7ebd91fbcc5379974d7556bf14a86fff2f8a;hp=df74d580ec2b954cd346b310438a976b9819bbca;hb=dac1bcab9007e0fe4c73fda4d6e5ac5b9add435c;hpb=5ed0a60203c1c93c5630894b4eca1f801241fe27 diff --git a/src/search.cpp b/src/search.cpp index df74d580..d54c7ebd 100644 --- a/src/search.cpp +++ b/src/search.cpp @@ -1643,7 +1643,7 @@ namespace { StateInfo st; Move ttMove, move; Value staticValue, bestValue, value, futilityBase, futilityValue; - bool isCheck, enoughMaterial, moveIsCheck; + bool isCheck, enoughMaterial, moveIsCheck, evasionPrunable; const TTEntry* tte = NULL; int moveCount = 0; bool pvNode = (beta - alpha != 1); @@ -1744,8 +1744,15 @@ namespace { } } - // Don't search captures and checks with negative SEE values - if ( !isCheck + // Detect blocking evasions that are candidate to be pruned + evasionPrunable = isCheck + && bestValue != -VALUE_INFINITE + && !pos.move_is_capture(move) + && pos.type_of_piece_on(move_from(move)) != KING + && !pos.can_castle(pos.side_to_move()); + + // Don't search moves with negative SEE values + if ( (!isCheck || evasionPrunable) && move != ttMove && !move_is_promotion(move) && pos.see_sign(move) < 0) @@ -1813,7 +1820,7 @@ namespace { assert(threadID >= 0 && threadID < ActiveThreads); assert(ActiveThreads > 1); - Position pos = Position(sp->pos); + Position pos(*sp->pos); CheckInfo ci(pos); SearchStack* ss = sp->sstack[threadID]; Value value = -VALUE_INFINITE; @@ -1955,7 +1962,7 @@ namespace { assert(threadID >= 0 && threadID < ActiveThreads); assert(ActiveThreads > 1); - Position pos = Position(sp->pos); + Position pos(*sp->pos); CheckInfo ci(pos); SearchStack* ss = sp->sstack[threadID]; Value value = -VALUE_INFINITE; @@ -2950,7 +2957,6 @@ namespace { assert(ActiveThreads > 1); SplitPoint* splitPoint; - int i; lock_grab(&MPLock); @@ -2967,7 +2973,7 @@ namespace { splitPoint = SplitPointStack[master] + Threads[master].activeSplitPoints; Threads[master].activeSplitPoints++; - // Initialize the split point object and copy current position + // Initialize the split point object splitPoint->parent = Threads[master].splitPoint; splitPoint->finished = false; splitPoint->ply = ply; @@ -2981,37 +2987,40 @@ namespace { splitPoint->mp = mp; splitPoint->moves = *moves; splitPoint->cpus = 1; - splitPoint->pos.copy(p); + splitPoint->pos = &p; splitPoint->parentSstack = sstck; - for (i = 0; i < ActiveThreads; i++) + for (int 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)); + Threads[master].idle = false; + Threads[master].stop = false; 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++) + // Allocate available threads setting idle flag to false + for (int i = 0; i < ActiveThreads && splitPoint->cpus < MaxThreadsPerSplitPoint; i++) if (thread_is_available(i, master)) { - memcpy(splitPoint->sstack[i], sstck, (ply+1) * sizeof(SearchStack)); + Threads[i].idle = false; + Threads[i].stop = false; Threads[i].splitPoint = splitPoint; splitPoint->slaves[i] = 1; splitPoint->cpus++; } + assert(splitPoint->cpus > 1); + + // We can release the lock because master and slave threads are already booked + lock_release(&MPLock); + // Tell the threads that they have work to do. This will make them leave - // their idle loop. - for (i = 0; i < ActiveThreads; i++) + // their idle loop. But before copy search stack tail for each thread. + for (int i = 0; i < ActiveThreads; i++) if (i == master || splitPoint->slaves[i]) { - Threads[i].workIsWaiting = true; - Threads[i].idle = false; - Threads[i].stop = false; + memcpy(splitPoint->sstack[i] + ply - 1, sstck + ply - 1, 3 * sizeof(SearchStack)); + Threads[i].workIsWaiting = true; // This makes the slave to exit from idle_loop() } - lock_release(&MPLock); - // Everything is set up. The master thread enters the idle loop, from // which it will instantly launch a search, because its workIsWaiting // slot is 'true'. We send the split point as a second parameter to the