Skip to content
This repository has been archived by the owner on Nov 2, 2022. It is now read-only.

Commit

Permalink
- Position::long_key → hash_keyのようにrename
Browse files Browse the repository at this point in the history
- Key128,Key256に暗黙のKeyへの変換を無くす。

- benchコマンドで結果に無駄な改行が出力されていたの修正。

- prefetchのコード、HASH_KEYが128bitになった時に間違えていたの修正。
  - 間違ってたと思ったら、アドレス計算自体はこれで合ってた…。
  // V7.01rr
  • Loading branch information
yaneurao committed Apr 24, 2022
1 parent eef3ac8 commit 9273f04
Show file tree
Hide file tree
Showing 9 changed files with 52 additions and 39 deletions.
4 changes: 2 additions & 2 deletions source/engine/yaneuraou-engine/yaneuraou-search.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1479,7 +1479,7 @@ namespace {
// excludedMoveがある(singular extension時)は、異なるentryにアクセスするように。
// ただし、このときpos.key()のbit0を破壊することは許されないので、make_key()でbit0はクリアしておく。
// excludedMoveがMOVE_NONEの時はkeyを変更してはならない。
posKey = excludedMove == MOVE_NONE ? pos.long_key() : pos.long_key() ^ HASH_KEY(make_key(excludedMove));
posKey = excludedMove == MOVE_NONE ? pos.hash_key() : pos.hash_key() ^ HASH_KEY(make_key(excludedMove));

tte = TT.probe(posKey, ss->ttHit);

Expand Down Expand Up @@ -2993,7 +2993,7 @@ namespace {
// Transposition table lookup
// 置換表のlookup

posKey = pos.long_key();
posKey = pos.hash_key();
tte = TT.probe(posKey, ss->ttHit);
ttValue = ss->ttHit ? value_from_tt(tte->value(), ss->ply) : VALUE_NONE;
ttMove = ss->ttHit ? pos.to_move(tte->move()) : MOVE_NONE;
Expand Down
10 changes: 8 additions & 2 deletions source/extra/key128.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ struct alignas(16) Key128
#endif
}

operator Key() const { return extract64<0>(); }
// これ暗黙で変換するの便利だが、バグに気づかずに危ない意味があるな…。
//operator Key() const { return extract64<0>(); }

// _u64[n]を取り出す。SSE4の命令が使えるときはそれを使う。
// n == 0なら下位64bit、n == 1なら上位64bitが取り出される。
Expand Down Expand Up @@ -134,7 +135,7 @@ struct alignas(32) Key256
#endif
}

operator Key() const { return extract64<0>(); }
//operator Key() const { return extract64<0>(); }

// p[n]を取り出す。SSE4の命令が使えるときはそれを使う。
template <int n>
Expand Down Expand Up @@ -183,4 +184,9 @@ struct std::hash<Key256> {
}
};

// HASH_KEYをKeyに変換する。
static Key hash_key_to_key(const Key key) { return key ; }
static Key hash_key_to_key(const Key128& key) { return key.extract64<0>(); }
static Key hash_key_to_key(const Key256& key) { return key.extract64<0>(); }

#endif // _KEY128_H_
10 changes: 5 additions & 5 deletions source/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1158,7 +1158,7 @@ void Position::do_move_impl(Move m, StateInfo& new_st, bool givesCheck)

// なるべく早い段階でのTTに対するprefetch
// 駒打ちのときはこの時点でTT entryのアドレスが確定できる
const Key key = k + h;
const HASH_KEY key = k + h;
prefetch(TT.first_entry(key));
#if defined(USE_EVAL_HASH)
Eval::prefetch_evalhash(key);
Expand Down Expand Up @@ -1323,7 +1323,7 @@ void Position::do_move_impl(Move m, StateInfo& new_st, bool givesCheck)
k += Zobrist::psq[to][moved_after_pc];

// 駒打ちでないときはprefetchはこの時点まで延期される。
const Key key = k + h;
const HASH_KEY key = k + h;
prefetch(TT.first_entry(key));
#if defined(USE_EVAL_HASH)
Eval::prefetch_evalhash(key);
Expand Down Expand Up @@ -1412,11 +1412,11 @@ void Position::do_move_impl(Move m, StateInfo& new_st, bool givesCheck)

// ある指し手を指した後のhash keyを返す。
Key Position::key_after(Move m) const {
return (Key)long_key_after(m);
return hash_key_to_key(hash_key_after(m));
}

// ある指し手を指した後のhash keyを返す。
HASH_KEY Position::long_key_after(Move m) const {
HASH_KEY Position::hash_key_after(Move m) const {

Color Us = side_to_move();
auto k = st->board_key_ ^ Zobrist::side;
Expand Down Expand Up @@ -1645,7 +1645,7 @@ void Position::do_null_move(StateInfo& newSt) {
//  prefetchのスケジューラーが処理しきれない可能性が…。
// CPUによっては有効なので一応やっておく。

const Key key = st->key();
const HASH_KEY key = st->hash_key();
prefetch(TT.first_entry(key));

// これは、さっきアクセスしたところのはずなので意味がない。
Expand Down
20 changes: 10 additions & 10 deletions source/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,15 @@ struct StateInfo {
// board_key()は盤面のhash。hand_key()は手駒のhash。それぞれ加算したのがkey() 盤面のhash。
// board_key()のほうは、手番も込み。

Key key() const { return long_key(); }
Key board_key() const { return board_long_key(); }
Key hand_key() const { return hand_long_key(); }
Key key() const { return hash_key_to_key(hash_key()); }
Key board_key() const { return hash_key_to_key(board_hash_key()); }
Key hand_key() const { return hash_key_to_key(hand_hash_key()); }

// HASH_KEY_BITSが128のときはKey128が返るhash key,256のときはKey256

HASH_KEY long_key() const { return board_key_ + hand_key_; }
HASH_KEY board_long_key() const { return board_key_; }
HASH_KEY hand_long_key() const { return hand_key_; }
HASH_KEY hash_key() const { return board_key_ + hand_key_; }
HASH_KEY board_hash_key() const { return board_key_ ; }
HASH_KEY hand_hash_key() const { return hand_key_; }

// 現局面で手番側に対して王手をしている駒のbitboard
Bitboard checkersBB;
Expand Down Expand Up @@ -529,15 +529,15 @@ class Position
// --- Accessing hash keys

// StateInfo::key()への簡易アクセス。
Key key() const { return st->key(); }
HASH_KEY long_key() const { return st->long_key(); }
Key key() const { return st->key() ; }
HASH_KEY hash_key() const { return st->hash_key(); }

// ある指し手を指した後のhash keyを返す。
// 将棋だとこの計算にそこそこ時間がかかるので、通常の探索部でprefetch用に
// これを計算するのはあまり得策ではないが、詰将棋ルーチンでは置換表を投機的に
// prefetchできるとずいぶん速くなるのでこの関数を用意しておく。
Key key_after(Move m) const;
HASH_KEY long_key_after(Move m) const;
Key key_after (Move m) const;
HASH_KEY hash_key_after(Move m) const;

// --- misc

Expand Down
2 changes: 0 additions & 2 deletions source/testcmd/benchmark.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,8 +210,6 @@ void bench_cmd(Position& current, istringstream& is)
<< "\nNodes searched/second(main thread) : " << 1000 * nodes_searched_main / elapsed;
#endif

cout << endl;

// 終了したことを出力しないと他のスクリプトから呼び出した時に終了判定にこまる。
cout << "\n==========================="
<< "\nThe bench command has completed." << sync_endl;
Expand Down
15 changes: 9 additions & 6 deletions source/tt.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,12 +253,15 @@ TTEntry* TranspositionTable::read_probe(const Key key_for_index, const TTEntry::
void TTEntry::save(Key k, Value v, bool pv , Bound b, Depth d, Move m, Value ev) { save_((TTEntry::KEY_TYPE)(k >> 1) ,v, pv, b, d, m, ev);}
void TTEntry::save(Key128& k, Value v, bool pv , Bound b, Depth d, Move m, Value ev) { save_((TTEntry::KEY_TYPE) k.extract64<1>() ,v, pv, b, d, m, ev);}
void TTEntry::save(Key256& k, Value v, bool pv , Bound b, Depth d, Move m, Value ev) { save_((TTEntry::KEY_TYPE) k.extract64<1>() ,v, pv, b, d, m, ev);}
TTEntry* TranspositionTable::probe (const Key key, bool& found) const { return probe(key ,(TTEntry::KEY_TYPE)(key >> 1), found); }
TTEntry* TranspositionTable::probe (const Key128& key, bool& found) const { return probe(key.extract64<0>(),(TTEntry::KEY_TYPE)(key.extract64<1>()), found); }
TTEntry* TranspositionTable::probe (const Key256& key, bool& found) const { return probe(key.extract64<0>(),(TTEntry::KEY_TYPE)(key.extract64<1>()), found); }
TTEntry* TranspositionTable::read_probe(const Key key, bool& found) const { return read_probe(key ,(TTEntry::KEY_TYPE)(key >> 1 ), found); }
TTEntry* TranspositionTable::read_probe(const Key128& key, bool& found) const { return read_probe(key.extract64<0>(),(TTEntry::KEY_TYPE)(key.extract64<1>()), found); }
TTEntry* TranspositionTable::read_probe(const Key256& key, bool& found) const { return read_probe(key.extract64<0>(),(TTEntry::KEY_TYPE)(key.extract64<1>()), found); }
TTEntry* TranspositionTable::probe (const Key key, bool& found) const { return probe(key ,(TTEntry::KEY_TYPE)(key >> 1 ), found); }
TTEntry* TranspositionTable::probe (const Key128& key, bool& found) const { return probe(key.extract64<0>(),(TTEntry::KEY_TYPE)(key.extract64<1>()), found); }
TTEntry* TranspositionTable::probe (const Key256& key, bool& found) const { return probe(key.extract64<0>(),(TTEntry::KEY_TYPE)(key.extract64<1>()), found); }
TTEntry* TranspositionTable::read_probe (const Key key, bool& found) const { return read_probe(key ,(TTEntry::KEY_TYPE)(key >> 1 ), found); }
TTEntry* TranspositionTable::read_probe (const Key128& key, bool& found) const { return read_probe(key.extract64<0>(),(TTEntry::KEY_TYPE)(key.extract64<1>()), found); }
TTEntry* TranspositionTable::read_probe (const Key256& key, bool& found) const { return read_probe(key.extract64<0>(),(TTEntry::KEY_TYPE)(key.extract64<1>()), found); }
TTEntry* TranspositionTable::first_entry(const Key key) const { return _first_entry(key ); }
TTEntry* TranspositionTable::first_entry(const Key128& key) const { return _first_entry(key.extract64<0>()); }
TTEntry* TranspositionTable::first_entry(const Key256& key) const { return _first_entry(key.extract64<0>()); }

int TranspositionTable::hashfull() const
{
Expand Down
26 changes: 16 additions & 10 deletions source/tt.h
Original file line number Diff line number Diff line change
Expand Up @@ -175,7 +175,22 @@ struct TranspositionTable {

// keyを元にClusterのindexを求めて、その最初のTTEntry*を返す。
// ※ ここで渡されるkeyのbit 0は局面の手番フラグ(Position::side_to_move())であると仮定している。
TTEntry* first_entry(const Key key) const {
TTEntry* first_entry(const Key key) const;
TTEntry* first_entry(const Key128& key) const;
TTEntry* first_entry(const Key256& key) const;

#if defined(EVAL_LEARN)
// スレッド数が変更になった時にThread.set()から呼び出される。
// これに応じて、スレッドごとに保持しているTTを初期化する。
void init_tt_per_thread();
#endif

private:
friend struct TTEntry;

// keyを元にClusterのindexを求めて、その最初のTTEntry*を返す。内部実装用。
// ※ ここで渡されるkeyのbit 0は局面の手番フラグ(Position::side_to_move())であると仮定している。
TTEntry* _first_entry(const Key key) const {
// Stockfishのコード
// mul_hi64は、64bit * 64bitの掛け算をして下位64bitを取得する関数。
//return &table[mul_hi64(key, clusterCount)].entry[0];
Expand Down Expand Up @@ -203,15 +218,6 @@ struct TranspositionTable {
return &table[(index << 1) | ((u64)key & 1)].entry[0];
}

#if defined(EVAL_LEARN)
// スレッド数が変更になった時にThread.set()から呼び出される。
// これに応じて、スレッドごとに保持しているTTを初期化する。
void init_tt_per_thread();
#endif

private:
friend struct TTEntry;

// この置換表が保持しているクラスター数。
// Stockfishはresize()ごとに毎回新しく置換表を確保するが、やねうら王では
// そこは端折りたいので、毎回は確保しない。そのため前回サイズがここに格納されていないと
Expand Down
2 changes: 1 addition & 1 deletion source/types.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ namespace Search {
return false;

pos.do_move(pv[0], st, pos.gives_check(pv[0]));
TTEntry* tte = TT.read_probe(pos.state()->long_key(), ttHit);
TTEntry* tte = TT.read_probe(pos.state()->hash_key(), ttHit);
Move m;
if (ttHit)
{
Expand Down
2 changes: 1 addition & 1 deletion source/usi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ namespace USI
// ただし置換表を破壊されるとbenchコマンドの時にシングルスレッドなのに探索内容の同一性が保証されなくて
// 困るのでread_probe()を用いる。
bool found;
auto* tte = TT.read_probe(pos.state()->long_key(), found);
auto* tte = TT.read_probe(pos.state()->hash_key(), found);

// 置換表になかった
if (!found)
Expand Down

0 comments on commit 9273f04

Please sign in to comment.