検討用のMultiPV実装について

近頃うちの子(スクラッチで作ってるGo言語プログラム)がそこそこまともに動くようになってきたので調子に乗って検討に使えるように改造してみた。

go infinite対応とMultiPV対応である。

shotgunやHefeweizenでも両方非対応である。(一説にはそれでニコ生で使われないという話もあるらしい)

 

go infinite対応は適当でいい。とりあえず,infiniteをbyoyomi 3600000と同値としといた。stopコマンド対応も難しくはない。探索停止ステータスに移行させればいい。

 

で,MultiPVであるが,単純な実装としてはdepth1で最善手定めたあと,それを候補手から外して次善手を求めればいい。あとは欲しい数だけ繰り返してってルーチンを探索深さを進めながら繰り返せば問題ない。やねうら王もこの手順だ。

しかし考えてみるとMultiPVの手数が増えると単純にほぼ比例した探索時間が必要になる。そもそもシングルスレッド探索なのに惜しい気がしたので次のような実装を試みた。

 

メインスレッドは非MultiPVと同じ。最善手探索の反復深化を進める。

次善手以降はメインスレッドが探索した最善手に呼応して探索する。つまりdepth n mutipv 1が終了することにより深さnの最善手が求まった直後にdepth n multipv 2の探索を『別スレッド』でスタートする。

同様にdepth n mutipv mが終了することによりm手までの候補が求まった直後にdepth n multipv m+1の探索をスタートする。

これにより多スレッドの並列化効率を度外視すれば,メインスレッドは非MultiPVと同じ時間で探索深さが進められるし,次善手以降はそれまでの候補手が決定直後から探索がスタートしているため事実上最速で求まる気がする。

シングルスレッド探索を別々に走らせているだけなので,やねうら王などのLazy SMPのサポートスレッドはどうしたらいいかちょっと分からない。

 

一応以上の実装を全探索スレッドをシングルでGo言語実装してみた。初期局面は6秒強でdepth7まで探索可能であるし,その頃にはdepth6 multipv 5くらいまで他候補手も求まっている。

 

問題は出力であるが,depth1のmultipv 1~mその次にdepth2のmultipv 1~mと来るのが従来型であるが,この順が相当狂うことになる。

具体的には将棋所はこの順を期待しているところがあって非常に見づらい。ShogiGUIはこの辺を柔軟にクリアしてくれているようで問題なかった。同じ探索深さにならないが他のエンジンでもアリなんじゃないかと思う。多分並列化効率は上回るんじゃないかな。

    for depth := 1; depth < 15 && !stop; depth++ {
        loop(po, depth, 0)
        go func(depth int) {
            for PVIdx := 1; PVIdx < multipv; PVIdx++ {
                loop(po, depth, PVIdx)
            }
        }(depth)
    }

 出力はmutexでスレッドセーフを保証してる。

  

結構改良したけど,そもそも探索速度が遅いので強くなったのはちょっとだけのようだ。余裕の頓死である。 

 

floodgateでのレーティングでgo_test01が2000くらいでgo_test02が2600くらいなので強くなってた気がしただけのようである。このレート帯は相手がいないだけなのね。 

特に意味はない。それなのになぜか休日の昼間に更にPonderを組み込んでいる。

次はGPSfishくらいが目標か。(そんなことより選手権・・・)

---

3月30日追記

忙しいはずなのについうっかりやねうら王に実験実装してみた。

メインスレッドの探索速度をあまり落とさずMultiPVになるのだが,multipv 2側のスレッドが速い場合と遅い場合があることが分かった。早い場合は同じdepthで追従してレスポンスがあるが,遅い場合はdepth3つ以上取り残される。

遅い場合ってのはLazy SMPの恩恵が薄いんだろうと推察される。(Lazy SMPのスレッド群はメインスレッドに追従しているので)

結果が出ると確かに納得する部分があるのだがあまり美味しい改造と言えない感じがしている。multipv 2側にスレッドを何割か分けてやると良いんだろうが,本末転倒な気がする。

multipv 2以降を他のマシンで探索する疎結合クラスタとか考えだしてどんどん選手権から離れていってたりする年度末。