mirror of
https://github.com/sockspls/badfish
synced 2025-04-30 00:33:09 +00:00
Always save static value and kingDanger to TT
Around 5% speed-up No functional change Signed-off-by: Marco Costalba <mcostalba@gmail.com>
This commit is contained in:
parent
de0c9e84ca
commit
226bd54064
4 changed files with 32 additions and 27 deletions
|
@ -1095,7 +1095,7 @@ namespace {
|
||||||
if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
|
if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
|
||||||
{
|
{
|
||||||
// Refresh tte entry to avoid aging
|
// Refresh tte entry to avoid aging
|
||||||
TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove);
|
TT.store(posKey, tte->value(), tte->type(), tte->depth(), ttMove, tte->static_value(), tte->king_danger());
|
||||||
|
|
||||||
ss[ply].currentMove = ttMove; // Can be MOVE_NONE
|
ss[ply].currentMove = ttMove; // Can be MOVE_NONE
|
||||||
return value_from_tt(tte->value(), ply);
|
return value_from_tt(tte->value(), ply);
|
||||||
|
@ -1106,8 +1106,11 @@ namespace {
|
||||||
isCheck = pos.is_check();
|
isCheck = pos.is_check();
|
||||||
if (!isCheck)
|
if (!isCheck)
|
||||||
{
|
{
|
||||||
if (tte && (tte->type() & VALUE_TYPE_EVAL))
|
if (tte && tte->static_value() != VALUE_NONE)
|
||||||
ss[ply].eval = value_from_tt(tte->value(), ply);
|
{
|
||||||
|
ss[ply].eval = tte->static_value();
|
||||||
|
ei.kingDanger[pos.side_to_move()] = tte->king_danger();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
ss[ply].eval = evaluate(pos, ei, threadID);
|
ss[ply].eval = evaluate(pos, ei, threadID);
|
||||||
|
|
||||||
|
@ -1385,13 +1388,13 @@ namespace {
|
||||||
return bestValue;
|
return bestValue;
|
||||||
|
|
||||||
if (bestValue <= oldAlpha)
|
if (bestValue <= oldAlpha)
|
||||||
TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE);
|
TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, depth, MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
|
||||||
|
|
||||||
else if (bestValue >= beta)
|
else if (bestValue >= beta)
|
||||||
{
|
{
|
||||||
TM.incrementBetaCounter(pos.side_to_move(), depth, threadID);
|
TM.incrementBetaCounter(pos.side_to_move(), depth, threadID);
|
||||||
move = ss[ply].pv[ply];
|
move = ss[ply].pv[ply];
|
||||||
TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move);
|
TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, depth, move, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
|
||||||
if (!pos.move_is_capture_or_promotion(move))
|
if (!pos.move_is_capture_or_promotion(move))
|
||||||
{
|
{
|
||||||
update_history(pos, move, depth, movesSearched, moveCount);
|
update_history(pos, move, depth, movesSearched, moveCount);
|
||||||
|
@ -1399,7 +1402,7 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss[ply].pv[ply]);
|
TT.store(posKey, value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, depth, ss[ply].pv[ply], ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
|
||||||
|
|
||||||
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
||||||
|
|
||||||
|
@ -1449,8 +1452,6 @@ namespace {
|
||||||
|
|
||||||
if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
|
if (!PvNode && tte && ok_to_use_TT(tte, depth, beta, ply))
|
||||||
{
|
{
|
||||||
assert(tte->type() != VALUE_TYPE_EVAL);
|
|
||||||
|
|
||||||
ss[ply].currentMove = ttMove; // Can be MOVE_NONE
|
ss[ply].currentMove = ttMove; // Can be MOVE_NONE
|
||||||
return value_from_tt(tte->value(), ply);
|
return value_from_tt(tte->value(), ply);
|
||||||
}
|
}
|
||||||
|
@ -1460,8 +1461,11 @@ namespace {
|
||||||
// Evaluate the position statically
|
// Evaluate the position statically
|
||||||
if (isCheck)
|
if (isCheck)
|
||||||
staticValue = -VALUE_INFINITE;
|
staticValue = -VALUE_INFINITE;
|
||||||
else if (tte && (tte->type() & VALUE_TYPE_EVAL))
|
else if (tte && tte->static_value() != VALUE_NONE)
|
||||||
staticValue = value_from_tt(tte->value(), ply);
|
{
|
||||||
|
staticValue = tte->static_value();
|
||||||
|
ei.kingDanger[pos.side_to_move()] = tte->king_danger();
|
||||||
|
}
|
||||||
else
|
else
|
||||||
staticValue = evaluate(pos, ei, threadID);
|
staticValue = evaluate(pos, ei, threadID);
|
||||||
|
|
||||||
|
@ -1479,7 +1483,7 @@ namespace {
|
||||||
{
|
{
|
||||||
// Store the score to avoid a future costly evaluation() call
|
// Store the score to avoid a future costly evaluation() call
|
||||||
if (!isCheck && !tte && ei.kingDanger[pos.side_to_move()] == 0)
|
if (!isCheck && !tte && ei.kingDanger[pos.side_to_move()] == 0)
|
||||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EV_LO, Depth(-127*OnePly), MOVE_NONE);
|
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, Depth(-127*OnePly), MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
|
||||||
|
|
||||||
return bestValue;
|
return bestValue;
|
||||||
}
|
}
|
||||||
|
@ -1577,20 +1581,19 @@ namespace {
|
||||||
{
|
{
|
||||||
// If bestValue isn't changed it means it is still the static evaluation
|
// If bestValue isn't changed it means it is still the static evaluation
|
||||||
// of the node, so keep this info to avoid a future evaluation() call.
|
// of the node, so keep this info to avoid a future evaluation() call.
|
||||||
ValueType type = (bestValue == staticValue && !ei.kingDanger[pos.side_to_move()] ? VALUE_TYPE_EV_UP : VALUE_TYPE_UPPER);
|
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_UPPER, d, MOVE_NONE, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
|
||||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), type, d, MOVE_NONE);
|
|
||||||
}
|
}
|
||||||
else if (bestValue >= beta)
|
else if (bestValue >= beta)
|
||||||
{
|
{
|
||||||
move = ss[ply].pv[ply];
|
move = ss[ply].pv[ply];
|
||||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move);
|
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_LOWER, d, move, ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
|
||||||
|
|
||||||
// Update killers only for good checking moves
|
// Update killers only for good checking moves
|
||||||
if (!pos.move_is_capture_or_promotion(move))
|
if (!pos.move_is_capture_or_promotion(move))
|
||||||
update_killers(move, ss[ply]);
|
update_killers(move, ss[ply]);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, d, ss[ply].pv[ply]);
|
TT.store(pos.get_key(), value_to_tt(bestValue, ply), VALUE_TYPE_EXACT, d, ss[ply].pv[ply], ss[ply].eval, ei.kingDanger[pos.side_to_move()]);
|
||||||
|
|
||||||
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
assert(bestValue > -VALUE_INFINITE && bestValue < VALUE_INFINITE);
|
||||||
|
|
||||||
|
|
|
@ -111,7 +111,7 @@ inline TTEntry* TranspositionTable::first_entry(const Key posKey) const {
|
||||||
/// is bigger than the depth of t2. A TTEntry of type VALUE_TYPE_EVAL
|
/// is bigger than the depth of t2. A TTEntry of type VALUE_TYPE_EVAL
|
||||||
/// never replaces another entry for the same position.
|
/// never replaces another entry for the same position.
|
||||||
|
|
||||||
void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, Move m) {
|
void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d, Move m, Value statV, Value kingD) {
|
||||||
|
|
||||||
TTEntry *tte, *replace;
|
TTEntry *tte, *replace;
|
||||||
uint32_t posKey32 = posKey >> 32; // Use the high 32 bits as key
|
uint32_t posKey32 = posKey >> 32; // Use the high 32 bits as key
|
||||||
|
@ -125,7 +125,7 @@ void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d,
|
||||||
if (m == MOVE_NONE)
|
if (m == MOVE_NONE)
|
||||||
m = tte->move();
|
m = tte->move();
|
||||||
|
|
||||||
*tte = TTEntry(posKey32, v, t, d, m, generation);
|
*tte = TTEntry(posKey32, v, t, d, m, generation, statV, kingD);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
else if (i == 0) // replace would be a no-op in this common case
|
else if (i == 0) // replace would be a no-op in this common case
|
||||||
|
@ -138,7 +138,7 @@ void TranspositionTable::store(const Key posKey, Value v, ValueType t, Depth d,
|
||||||
if (c1 + c2 + c3 > 0)
|
if (c1 + c2 + c3 > 0)
|
||||||
replace = tte;
|
replace = tte;
|
||||||
}
|
}
|
||||||
*replace = TTEntry(posKey32, v, t, d, m, generation);
|
*replace = TTEntry(posKey32, v, t, d, m, generation, statV, kingD);
|
||||||
writes++;
|
writes++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -211,7 +211,7 @@ void TranspositionTable::insert_pv(const Position& pos, Move pv[]) {
|
||||||
{
|
{
|
||||||
TTEntry *tte = retrieve(p.get_key());
|
TTEntry *tte = retrieve(p.get_key());
|
||||||
if (!tte || tte->move() != pv[i])
|
if (!tte || tte->move() != pv[i])
|
||||||
store(p.get_key(), VALUE_NONE, VALUE_TYPE_NONE, Depth(-127*OnePly), pv[i]);
|
store(p.get_key(), VALUE_NONE, VALUE_TYPE_NONE, Depth(-127*OnePly), pv[i], VALUE_NONE, VALUE_NONE);
|
||||||
p.do_move(pv[i], st);
|
p.do_move(pv[i], st);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
12
src/tt.h
12
src/tt.h
|
@ -54,9 +54,11 @@ class TTEntry {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
TTEntry() {}
|
TTEntry() {}
|
||||||
TTEntry(uint32_t k, Value v, ValueType t, Depth d, Move m, int generation)
|
TTEntry(uint32_t k, Value v, ValueType t, Depth d, Move m, int generation,
|
||||||
|
Value statV, Value kingD)
|
||||||
: key_ (k), data((m & 0x1FFFF) | (t << 20) | (generation << 23)),
|
: key_ (k), data((m & 0x1FFFF) | (t << 20) | (generation << 23)),
|
||||||
value_(int16_t(v)), depth_(int16_t(d)) {}
|
value_(int16_t(v)), depth_(int16_t(d)),
|
||||||
|
staticValue_(int16_t(statV)), kingDanger_(int16_t(kingD)) {}
|
||||||
|
|
||||||
uint32_t key() const { return key_; }
|
uint32_t key() const { return key_; }
|
||||||
Depth depth() const { return Depth(depth_); }
|
Depth depth() const { return Depth(depth_); }
|
||||||
|
@ -64,12 +66,16 @@ public:
|
||||||
Value value() const { return Value(value_); }
|
Value value() const { return Value(value_); }
|
||||||
ValueType type() const { return ValueType((data >> 20) & 7); }
|
ValueType type() const { return ValueType((data >> 20) & 7); }
|
||||||
int generation() const { return (data >> 23); }
|
int generation() const { return (data >> 23); }
|
||||||
|
Value static_value() const { return Value(staticValue_); }
|
||||||
|
Value king_danger() const { return Value(kingDanger_); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
uint32_t key_;
|
uint32_t key_;
|
||||||
uint32_t data;
|
uint32_t data;
|
||||||
int16_t value_;
|
int16_t value_;
|
||||||
int16_t depth_;
|
int16_t depth_;
|
||||||
|
int16_t staticValue_;
|
||||||
|
int16_t kingDanger_;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -97,7 +103,7 @@ public:
|
||||||
~TranspositionTable();
|
~TranspositionTable();
|
||||||
void set_size(size_t mbSize);
|
void set_size(size_t mbSize);
|
||||||
void clear();
|
void clear();
|
||||||
void store(const Key posKey, Value v, ValueType type, Depth d, Move m);
|
void store(const Key posKey, Value v, ValueType type, Depth d, Move m, Value statV, Value kingD);
|
||||||
TTEntry* retrieve(const Key posKey) const;
|
TTEntry* retrieve(const Key posKey) const;
|
||||||
void prefetch(const Key posKey) const;
|
void prefetch(const Key posKey) const;
|
||||||
void new_search();
|
void new_search();
|
||||||
|
|
|
@ -36,11 +36,7 @@ enum ValueType {
|
||||||
VALUE_TYPE_NONE = 0,
|
VALUE_TYPE_NONE = 0,
|
||||||
VALUE_TYPE_UPPER = 1, // Upper bound
|
VALUE_TYPE_UPPER = 1, // Upper bound
|
||||||
VALUE_TYPE_LOWER = 2, // Lower bound
|
VALUE_TYPE_LOWER = 2, // Lower bound
|
||||||
VALUE_TYPE_EVAL = 4, // Static evaluation value
|
VALUE_TYPE_EXACT = VALUE_TYPE_UPPER | VALUE_TYPE_LOWER
|
||||||
|
|
||||||
VALUE_TYPE_EXACT = VALUE_TYPE_UPPER | VALUE_TYPE_LOWER,
|
|
||||||
VALUE_TYPE_EV_UP = VALUE_TYPE_EVAL | VALUE_TYPE_UPPER,
|
|
||||||
VALUE_TYPE_EV_LO = VALUE_TYPE_EVAL | VALUE_TYPE_LOWER
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue