Optimisation of Position::see and Position::see_sign

Stephane's patch removes the only usage of Position::see, where the
returned value isn't immediately compared with a value. So I replaced
this function by its optimised and more specific version see_ge. This
function also supersedes the function Position::see_sign.

bool Position::see_ge(Move m, Value v) const;

This function tests if the SEE of a move is greater or equal than a
given value. We use forward iteration on captures instread of backward
one, therefore we don't need the swapList array. Also we stop as soon
as we have enough information to obtain the result, avoiding unnecessary
calls to the min_attacker function.

Speed tests (Windows 7), 20 runs for each engine:
Test engine: mean 866648, st. dev. 5964
Base engine: mean 846751, st. dev. 22846
Speedup: 1.023

Speed test by Stephane Nicolet

Fishtest STC test:
LLR: 2.96 (-2.94,2.94) [0.00,5.00]
Total: 26040 W: 4675 L: 4442 D: 16923
http://tests.stockfishchess.org/tests/view/57f648990ebc59038170fa03

No functional change.
This commit is contained in:
atumanian
2016-10-06 20:55:10 +03:00
committed by Marco Costalba
parent 1e586288ca
commit 073eed590e
4 changed files with 67 additions and 87 deletions

View File

@@ -889,7 +889,7 @@ moves_loop: // When in check search starts from here
// Step 12. Extend checks
if ( givesCheck
&& !moveCountPruning
&& pos.see_sign(move) >= VALUE_ZERO)
&& pos.see_ge(move, VALUE_ZERO))
extension = ONE_PLY;
// Singular extension search. If all moves but one fail low on a search of
@@ -946,11 +946,11 @@ moves_loop: // When in check search starts from here
// Prune moves with negative SEE
if ( lmrDepth < 8
&& pos.see_sign(move) < Value(-35 * lmrDepth * lmrDepth))
&& !pos.see_ge(move, Value(-35 * lmrDepth * lmrDepth)))
continue;
}
else if ( depth < 7 * ONE_PLY
&& pos.see_sign(move) < Value(-35 * depth / ONE_PLY * depth / ONE_PLY))
&& !pos.see_ge(move, Value(-35 * depth / ONE_PLY * depth / ONE_PLY)))
continue;
}
@@ -992,7 +992,7 @@ moves_loop: // When in check search starts from here
// because the destination square is empty.
else if ( type_of(move) == NORMAL
&& type_of(pos.piece_on(to_sq(move))) != PAWN
&& pos.see(make_move(to_sq(move), from_sq(move))) < VALUE_ZERO)
&& !pos.see_ge(make_move(to_sq(move), from_sq(move)), VALUE_ZERO))
r -= 2 * ONE_PLY;
// Decrease/increase reduction for moves with a good/bad history
@@ -1302,7 +1302,7 @@ moves_loop: // When in check search starts from here
continue;
}
if (futilityBase <= alpha && pos.see(move) <= VALUE_ZERO)
if (futilityBase <= alpha && !pos.see_ge(move, VALUE_ZERO + 1))
{
bestValue = std::max(bestValue, futilityBase);
continue;
@@ -1317,7 +1317,7 @@ moves_loop: // When in check search starts from here
// Don't search moves with negative SEE values
if ( (!InCheck || evasionPrunable)
&& type_of(move) != PROMOTION
&& pos.see_sign(move) < VALUE_ZERO)
&& !pos.see_ge(move, VALUE_ZERO))
continue;
// Speculative prefetch as early as possible