python-shogiをベースにpythonで作った簡単な探索部を作って簡単な実験をしていたのが2年ほど前。見やすい簡単なプログラムなので改造等は簡単だが,相当遅いので色々と処理速度に不満があった。(もちろん今でも色んな評価関数の試作および学習実験には用いている。)
昨年末にGo言語で自作したのをちょっとずつ改良してきているが,blogの温故知新シリーズと合わせて良い実験材料になってきている。
前回差し手生成を3倍程度高速化したが,探索部全体的にはあまり速くなっていない。
その後,探索分岐で盤情報をディープコピーせずに指し手UnDoする改良を施し(池さんの本にも書かれている高速化),部分的に3割程度更に高速化した。
指し手生成の展開時に,あーこれだったら指し手属性ごとに別々に作れるなぁと思ってしまったので取り急ぎ打ち手だけ駒ごとに分解した。
で,またそのついでに王手時の合い駒だけ別に作成するのも簡単に拡張できるなぁと・・・
と色々やってると160~180knpsくらいまで出るようになってきた。特に王手時は王手回避ができているかどうかは一手進めて判定していたので合い駒が正確に打てると探索は相当高速化できる。(モロ温故知新ですな。npsじゃなくdepthが伸びる)
ついでに王手時の探索延長を加えた。これは諸刃の剣っぽい。詰み探索速度は抜群に速くなるが,王手の連続で駒を捨てる筋を優先して読むので詰みがありそうでない場合はそちらばかり探索して全然メインの探索が進まないことになる。酷いときには10秒以上かかっても2手先しか読めてないことも。延長し過ぎなのかも。別ルーチン化する前例が多いのはそういうととかとひとり納得してる。
また,floodgate対戦中にバグが見つかったので修正したはずだが,まだ微妙なので再確認する案件。Ponder探索中に相手側が先に投了した場合,探索データに前回分のゴミが残って次の新規対局時に非合法手がでることがあった。現在は解決したはずだがmax_movesの次の対戦が開始できてなかったので何か類似の不具合が残っている様子。こういったのはなかなか発覚しないので難しい。
また,現バージョンにしてレーティングが向上する期待をしていたのだが全く向上する気配がないので差し手生成部とかに致命的バグを増やしたのかもしれないなぁと悩み事を増やしている。(特にYSSに全敗である)
そんなことより選手権はどうかというとこれがベースでクラスタリングのコアになるのだが実はあんまり速度は要らない。対戦中継用のノートPCでGo言語のクラスタ管理プログラムが動いて,ネット越にそれぞれの探索エンジンに指示を送ることになる。Go言語だと複数のエンジンとのやり取りをリアルタイム化しやすいってのが主目的である。簡単に言うとログ管理に近い案件であるが,最終出力を担当する以上バグがあっては困る。高速応答が要求されるリアルタイムサーバの技術ではあるのだが,保守的に運用したいので上記アップデートは選手権コードには加えない予定だ。
まぁ,調子に乗って改造してしまったが,本来の方向ではなくなってしまった。Bitboard実装は128ビットレジスタが扱えてナンボの技術なのでGo言語ではやる気がしない。あ,でもLazy SMPなら簡単に組めそう。そしたらクラスタ間のやつも・・・。
そろそろ暴走を止めなければ死んでしまう(王手回避だけで週末徹夜しといて何を言うw)
選手権でAperyやきふわらべの活躍如何で次はRust弄ってる可能性があるかも。
ーーー
4月14日追記
座駆動で本件をネタにしたので記載しとく。
Aoba Zero,Crazy Shogiに勝ったと言ったけど,その後Crazy Shogiの方が相当強くなってるのでたぶんもう勝てない。
で,現地未発表の残りスライドは
・Go言語のよかったところ
・Go言語のつらいところ
- int int32 int64ですら明示的型変換を要求する
- abs min maxのような組み込み関数すら入ってない
- 三項演算子が使えない
- for分が遅い(C++比)
- インラインアセンブラが使えない(C++比)
後者は本件に向いてないので仕方ないって感じかな。