Aperyの置換表をStockfish7風にする [コンピュータ将棋]
<追記>一番重要なコミットを書き忘れていた上に、そのコミットで勝率が変わるかもしれないというひどさなので前に見たことがある人は一番下を見てください
LazySMPは(バグのせいかもしれないが)探索深さが浅いせいで単純比較だとR200ぐらい落ちたので、やる気もなくなったのだが、移植している時に気がついたのが置換表の仕様変更。
Lazy SMP移植してみたときは置換表については特に手を入れなかったので、改めてStockfishのソースコードを見て差異があるところを移植してみた。
やねうら王Blogでも解説されているように、ハッシュ1エントリをまとめてクラスタとして管理してL1キャッシュが効果的に動くようにしているという基本思想そのものは変わっていない。
以下、Aperyとの差異があると思われるコミット
・エントリに含まれているリハッシュ処理のタイミングがstore時じゃなくてprobe時にやるようにしている
probe時に格納先のアドレスを覚えておいて、store時はそのアドレスに書くだけになっている
これによって、似たようなクラスター探索ループ処理を2回動かさなくても良いようになった。
・Stockfish独自のパック処理
Stockfish7ではBoundとGenerationをまとめて1バイトにすることによって格納数を増やした。
Aperyの場合はエントリサイズが大きくしてあるので格納数は変わらないので手を付けなかった。
・置換表使用率の表示
(参考)連載やねうら王miniを強くしよう!7日目 | やねうら王 公式サイト http://ow.ly/WRdJd
やねうら王Blogに実装するべきと書かれていたが、Stockfishでもパフォーマンスの観点で一時的に消されていたらしいが復帰していた模様。
以前スローダウンすると間違った判断をされていたが、今どきのPCだと2ms程度なので気にするほどではないとのこと。
またやねうら王Blogにかかれているように、ハッシュ全体を検査したり、カウンタをつけるのではなく、頭の1000個のクラスタの中身を見て該当するかどうか調べているので、ハッシュサイズが大きくなったら問題が起きるとか、コア間の強豪が起きるとかもあまりないと思われる。
実際採用してみたが、いつもの4コア、2GB、3秒で2%ぐらい使うのがわかった。
数分放置してみたところキャッシュが98%で頭打ちになっていた。
32GB積んでいる8コアの第2回電脳戦モデルの場合、キャッシュに使えるサイズの最大値は16GBで、PCのコア数が倍なので、20分程度も長考すれば溢れることになる。
タイムマネージャーあたりの最適化の指針にはなるかもしれない
多分ほんのちょっとだけ速くなって、ほんのちょっとだけ遅くなったので、強さは変わってないと思う。
<追記>強くなっている可能性があるので下記参照
(一手1秒では50勝45敗5分、一手3秒では50勝41敗5分だった)
ちなみに、途中で取り込みミスがあったときは、R200ぐらい落ちたのだが、ミスの発生頻度を計算したところ、3局に1回おかしくなりそうだったので、まあ妥当なレーティングかなと思った。
<1.11追記>
肝心のものを書くのを忘れていた
・探索結果としての価値の低い値を格納しない
基本的に置換表に入るべき値は「探索が深い方がより正しい」という思想に基づいているはずだが、マルチスレッド処理をやっていると、タイミングでおかしくなる場合があると思われる(未調査)
https://github.com/official-stockfish/Stockfish/pull/347
ログの意味がよくわからないが、多分置換表のサイズをすごく小さくしても正しく動作するかどうかチェックしてたんだと思う(要調査)
あと開発中はベンチマークが大幅に下がったが、最終的にはほとんど下がらなかったどころか上がった?(要調査)
「キャッシュが入っていると思われる時に変な手を20局に1回ぐらい指す理由」は案外これかもしれないし、Lazy SMPが弱くなった理由はこれが入っていなかったからかもしれない
<さらに追記>
マージしてやってみたが見事にWスコアで、改善せず。探索深さが浅いのがどうにも致命的に思われる。
<さらに追記>
Aperyのソースコードのコメントにあるsize_はサイズではなくclusterCount_にするべきであろう。
あとコメントも間違っている
LazySMPは(バグのせいかもしれないが)探索深さが浅いせいで単純比較だとR200ぐらい落ちたので、やる気もなくなったのだが、移植している時に気がついたのが置換表の仕様変更。
Lazy SMP移植してみたときは置換表については特に手を入れなかったので、改めてStockfishのソースコードを見て差異があるところを移植してみた。
やねうら王Blogでも解説されているように、ハッシュ1エントリをまとめてクラスタとして管理してL1キャッシュが効果的に動くようにしているという基本思想そのものは変わっていない。
以下、Aperyとの差異があると思われるコミット
・エントリに含まれているリハッシュ処理のタイミングがstore時じゃなくてprobe時にやるようにしている
probe時に格納先のアドレスを覚えておいて、store時はそのアドレスに書くだけになっている
これによって、似たようなクラスター探索ループ処理を2回動かさなくても良いようになった。
commit 14cf27e6f65787a1f9c8e4759ae0fcc218f37d2d Author: mstemberaDate: Sat Dec 13 07:16:35 2014 +0000 Avoid searching TT twice for the same key/position during probe() and store(). Just keep the pointer and remove code from tt.cpp
・Stockfish独自のパック処理
Stockfish7ではBoundとGenerationをまとめて1バイトにすることによって格納数を増やした。
Aperyの場合はエントリサイズが大きくしてあるので格納数は変わらないので手を付けなかった。
commit ccd823a4ffd2ed3e60cb03ab49a841742bae1994 Author: Ron BritvichDate: Sat Jun 28 14:05:58 2014 -0400 Pack 3 TT entries in 32 bytes cluster Idea from Ron Britvich Code reworked by Marco Costalba and Joona Kiiski
・置換表使用率の表示
(参考)連載やねうら王miniを強くしよう!7日目 | やねうら王 公式サイト http://ow.ly/WRdJd
やねうら王Blogに実装するべきと書かれていたが、Stockfishでもパフォーマンスの観点で一時的に消されていたらしいが復帰していた模様。
commit a3b4e9e23ca7f8949336014468b872e57da85762 Author: Jean-Francois RomangDate: Sun Jan 25 08:57:51 2015 +0100 Ressurrect hashfull patch This is an old patch from Jean-Francois Romang to send UCI hashfull info to the GUI: https://github.com/mcostalba/Stockfish/pull/60/files It was wrongly judged as a slowdown, but it takes much less than 1 ms to run, indeed on my core i5 2.6Ghz it takes about 2 microsecs to run!
以前スローダウンすると間違った判断をされていたが、今どきのPCだと2ms程度なので気にするほどではないとのこと。
またやねうら王Blogにかかれているように、ハッシュ全体を検査したり、カウンタをつけるのではなく、頭の1000個のクラスタの中身を見て該当するかどうか調べているので、ハッシュサイズが大きくなったら問題が起きるとか、コア間の強豪が起きるとかもあまりないと思われる。
実際採用してみたが、いつもの4コア、2GB、3秒で2%ぐらい使うのがわかった。
数分放置してみたところキャッシュが98%で頭打ちになっていた。
32GB積んでいる8コアの第2回電脳戦モデルの場合、キャッシュに使えるサイズの最大値は16GBで、PCのコア数が倍なので、20分程度も長考すれば溢れることになる。
タイムマネージャーあたりの最適化の指針にはなるかもしれない
<追記>強くなっている可能性があるので下記参照
(一手1秒では50勝45敗5分、一手3秒では50勝41敗5分だった)
ちなみに、途中で取り込みミスがあったときは、R200ぐらい落ちたのだが、ミスの発生頻度を計算したところ、3局に1回おかしくなりそうだったので、まあ妥当なレーティングかなと思った。
<1.11追記>
肝心のものを書くのを忘れていた
・探索結果としての価値の低い値を格納しない
基本的に置換表に入るべき値は「探索が深い方がより正しい」という思想に基づいているはずだが、マルチスレッド処理をやっていると、タイミングでおかしくなる場合があると思われる(未調査)
commit eaeb63f1d03aa71edf719605a31d121bf086a03d Author: mstemberaDate: Sat May 9 17:43:57 2015 +0100 Smart TT save Don't overwrite more valuable data with less valuable data
https://github.com/official-stockfish/Stockfish/pull/347
ログの意味がよくわからないが、多分置換表のサイズをすごく小さくしても正しく動作するかどうかチェックしてたんだと思う(要調査)
あと開発中はベンチマークが大幅に下がったが、最終的にはほとんど下がらなかったどころか上がった?(要調査)
「キャッシュが入っていると思われる時に変な手を20局に1回ぐらい指す理由」は案外これかもしれないし、Lazy SMPが弱くなった理由はこれが入っていなかったからかもしれない
<さらに追記>
マージしてやってみたが見事にWスコアで、改善せず。探索深さが浅いのがどうにも致命的に思われる。
<さらに追記>
Aperyのソースコードのコメントにあるsize_はサイズではなくclusterCount_にするべきであろう。
あとコメントも間違っている
コメント 0