Position pos(*sp->pos);
CheckInfo ci(pos);
SearchStack* ss = sp->sstack[threadID];
+ StateInfo st;
Value value = -VALUE_INFINITE;
Move move;
int moveCount;
bool useFutilityPruning = sp->depth < 7 * OnePly //FIXME: sync with search
&& !isCheck;
- while ( lock_grab_bool(&(sp->lock))
- && sp->bestValue < sp->beta
+ lock_grab(&(sp->lock));
+
+ while ( sp->bestValue < sp->beta
&& !TM.thread_should_stop(threadID)
&& (move = sp->mp->get_next_move()) != MOVE_NONE)
{
if ( moveCount >= futility_move_count(sp->depth)
&& ok_to_prune(pos, move, ss[sp->ply].threatMove)
&& sp->bestValue > value_mated_in(PLY_MAX))
+ {
+ lock_grab(&(sp->lock));
continue;
+ }
// Value based pruning
Value futilityValueScaled = sp->futilityValue - moveCount * 8; //FIXME: sync with search
if (futilityValueScaled < sp->beta)
{
- if (futilityValueScaled > sp->bestValue) // Less then 1% of cases
- {
- lock_grab(&(sp->lock));
- if (futilityValueScaled > sp->bestValue)
- sp->bestValue = futilityValueScaled;
- lock_release(&(sp->lock));
- }
+ lock_grab(&(sp->lock));
+
+ if (futilityValueScaled > sp->bestValue)
+ sp->bestValue = futilityValueScaled;
continue;
}
}
- // Make and search the move.
- StateInfo st;
+ // Step 13. Make the move
pos.do_move(move, st, ci, moveIsCheck);
- // Try to reduce non-pv search depth by one ply if move seems not problematic,
+ // Step 14. Reduced search
// if the move fails high will be re-searched at full depth.
bool doFullDepthSearch = true;
}
}
- if (doFullDepthSearch) // Go with full depth non-pv search
+ // Step 15. Full depth search
+ if (doFullDepthSearch)
{
ss[sp->ply].reduction = Depth(0);
value = -search(pos, ss, -(sp->beta - 1), newDepth, sp->ply+1, true, threadID);
}
+
+ // Step 16. Undo move
pos.undo_move(move);
assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
- // New best move?
- if (value > sp->bestValue) // Less then 2% of cases
+ // Step 17. Check for new best move
+ lock_grab(&(sp->lock));
+
+ if (value > sp->bestValue && !TM.thread_should_stop(threadID))
{
- lock_grab(&(sp->lock));
- if (value > sp->bestValue && !TM.thread_should_stop(threadID))
+ sp->bestValue = value;
+ if (sp->bestValue >= sp->beta)
{
- sp->bestValue = value;
- if (sp->bestValue >= sp->beta)
- {
- sp->stopRequest = true;
- sp_update_pv(sp->parentSstack, ss, sp->ply);
- }
+ sp->stopRequest = true;
+ sp_update_pv(sp->parentSstack, ss, sp->ply);
}
- lock_release(&(sp->lock));
}
}
/* Here we have the lock still grabbed */
- sp->cpus--;
sp->slaves[threadID] = 0;
+ sp->cpus--;
lock_release(&(sp->lock));
}
Position pos(*sp->pos);
CheckInfo ci(pos);
SearchStack* ss = sp->sstack[threadID];
+ StateInfo st;
Value value = -VALUE_INFINITE;
int moveCount;
Move move;
- while ( lock_grab_bool(&(sp->lock))
- && sp->alpha < sp->beta
+ // Step 10. Loop through moves
+ // Loop through all legal moves until no moves remain or a beta cutoff occurs
+ lock_grab(&(sp->lock));
+
+ while ( sp->alpha < sp->beta
&& !TM.thread_should_stop(threadID)
&& (move = sp->mp->get_next_move()) != MOVE_NONE)
{
bool moveIsCheck = pos.move_is_check(move, ci);
bool captureOrPromotion = pos.move_is_capture_or_promotion(move);
- ss[sp->ply].currentMove = move;
-
- // Decide the new search depth
+ // 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;
- // Make and search the move.
- StateInfo st;
+ // Update current move
+ ss[sp->ply].currentMove = move;
+
+ // Step 12. Futility pruning (is omitted in PV nodes)
+
+ // Step 13. Make the move
pos.do_move(move, st, ci, moveIsCheck);
- // Try to reduce non-pv search depth by one ply if move seems not problematic,
+ // Step 14. Reduced search
// if the move fails high will be re-searched at full depth.
bool doFullDepthSearch = true;
}
}
- if (doFullDepthSearch) // Go with full depth non-pv search
+ // Step 15. Full depth search
+ if (doFullDepthSearch)
{
Value localAlpha = sp->alpha;
ss[sp->ply].reduction = Depth(0);
value = -search_pv(pos, ss, -sp->beta, -localAlpha, newDepth, sp->ply+1, threadID);
}
}
+
+ // Step 16. Undo move
pos.undo_move(move);
assert(value > -VALUE_INFINITE && value < VALUE_INFINITE);
- // New best move?
- if (value > sp->bestValue) // Less then 2% of cases
+ // Step 17. Check for new best move
+ lock_grab(&(sp->lock));
+
+ if (value > sp->bestValue && !TM.thread_should_stop(threadID))
{
- lock_grab(&(sp->lock));
- if (value > sp->bestValue && !TM.thread_should_stop(threadID))
+ sp->bestValue = value;
+ if (value > sp->alpha)
{
- sp->bestValue = value;
- if (value > sp->alpha)
- {
- // Ask threads to stop before to modify sp->alpha
- if (value >= sp->beta)
- sp->stopRequest = 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;
- }
+ // Ask threads to stop before to modify sp->alpha
+ if (value >= sp->beta)
+ sp->stopRequest = 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;
}
- lock_release(&(sp->lock));
}
}
/* Here we have the lock still grabbed */
- sp->cpus--;
sp->slaves[threadID] = 0;
+ sp->cpus--;
lock_release(&(sp->lock));
}