AperyのLazy SMP化するとどうなるか [コンピュータ将棋]
GithubのLazy SMPコミット見てたら、自分でも出来そうな気がしたので改造してみた。
大まかな実装自体はすぐ終わったが、(主にくだらないことで)ハマり、デバッグに一週間かかった。
以下ハマったポイント
・スレッドの管理の問題
YBWCでは、「親スレッドが動いた後、Depth5ぐらいになってSplitされた子スレッドが動く」という動きになっているので親=>子の順番で動くことが担保されていて適当なタイミングでスレッドをおこしても不具合が起きなかった。
Lazy SMPでは子スレッドのほうが親スレッドよりも先に反復深化が動く可能性があり、しかもの初期コミットではDepth0でサーチしてたりした。やねうら王Blogでも、メインスレッドの出力が1番目に来ていない場合がある。これがLazy SMPの特徴なので、これが正しい動作であるという前提で切り分けしないといけないのだが、別の問題とのコンボで割とはまった。
・BMI2ビルドが動かない環境なのにBMI2ビルドをしていて、Segmentation Faultを起こしていた
Evaluateの変数の代入でセグっていたので、自分のコードが間違っていると思いこみ、変数周りを見なおしていたが、Instructionのほうが問題だったというオチ(3日かかった(笑))
・ビルドしたファイルをsrc=>binにコピーしていなかった
デバッグはbinフォルダでやっていたのだが、当然、修正が反映されていない状況でデバッグをしていた。
いくらソースコードを見ても間違ってるように思えなかったので、寝起きにすっきりした頭で、クリーンビルドして実行したらすんなり動いた。
これで1日ぐらい潰したような。
日をまたぐと忘れるので公式アナウンス推奨のシンボリックリンク作成して試すようにした
・gdbが使いにくい
mingwのgdbだとエラーで止まってくれない
gdbでリダイレクトをするとエラーで止まってくれない
gdb上でリダイレクトありでgoコマンドを実行すると空白をひたすら送り続けるらしく、持ち時間0、秒読み0で探索が動いてしまう
これも1,2日ぐらい無駄にした気がする。とくに最後のやつがひどい。
・最適化ビルド
PGOやるにはsrcの下にシンボリックリンクを作るのが公式見解だった
詳しくは前のエントリ参照
・大樹の枝(配布版)との比較
設定
4コア、3秒(実質2.5秒)、ハッシュ2GB、先読み無し
NPS,5%~10%増し
探索深さ、0~-2(中盤妙にパフォーマンスが悪くなる場合がある)
というよくわからない状況になった。
ハッシュがヒットしているとカウントしないはずなのだが、探索深さが浅いのに数が多いというよくわからない状況になっている。
探索深さが2手浅いのが結構致命的で勝率は壊滅的だった。(ちょっと試した感じだとR200ぐらい落ちた)
本来なら8コアで伸びがあることを証明したいところだが、4コアのマシンしか持っていないので試せていない。
その後、あんまりひどいので探索周りを少しいじってたら、4コアでなんとなく互角っぽいLazy SMPバージョンが出来た(かもしれない)。探索深さ自体は変わっていないので、勝率は悪いはずだが、本家に存在する「4コア3秒のときに10局に1回ぐらい発生する中終盤で変な指し手を指すバグっぽい挙動(後述)」が改善された気がする(あくまでも「気がする」だけでちゃんと検証したわけではない)
・「4コア3秒のときに10局に1回ぐらい発生する中終盤で変な指し手を指すバグっぽい挙動」
割りとそれなりの頻度で、敗着っぽいのをいきなり指してしまう現象。
4コア3秒で指し手の候補が3つぐらい出てくるとき(Fail-Low連発してるとき?)に
0~2秒:3つぐらいの手で迷う
2~3秒:よりにもよって悪そうな手(無理攻め?)でロックされる
というのが、それなりの頻度である気がする。
電王トーナメントとかだと持ち時間制度なので、FailLowが発生したら持ち時間が伸びて解消されてると思うのだが、4コア1手3秒固定でやってると10局に1回ぐらいの頻度で発生しているように思う。(要出典)
・結論
すでにYBWCを実装している人は、電王トーナメントのような4コア前提ならやる意味は無い。
しかしマルチスレッド化をこれから実装する人はまずはLazySMPで実装してしまうのは良い方法だと思う。
大まかな実装自体はすぐ終わったが、(主にくだらないことで)ハマり、デバッグに一週間かかった。
以下ハマったポイント
・スレッドの管理の問題
YBWCでは、「親スレッドが動いた後、Depth5ぐらいになってSplitされた子スレッドが動く」という動きになっているので親=>子の順番で動くことが担保されていて適当なタイミングでスレッドをおこしても不具合が起きなかった。
Lazy SMPでは子スレッドのほうが親スレッドよりも先に反復深化が動く可能性があり、しかもの初期コミットではDepth0でサーチしてたりした。やねうら王Blogでも、メインスレッドの出力が1番目に来ていない場合がある。これがLazy SMPの特徴なので、これが正しい動作であるという前提で切り分けしないといけないのだが、別の問題とのコンボで割とはまった。
・BMI2ビルドが動かない環境なのにBMI2ビルドをしていて、Segmentation Faultを起こしていた
Evaluateの変数の代入でセグっていたので、自分のコードが間違っていると思いこみ、変数周りを見なおしていたが、Instructionのほうが問題だったというオチ(3日かかった(笑))
・ビルドしたファイルをsrc=>binにコピーしていなかった
デバッグはbinフォルダでやっていたのだが、当然、修正が反映されていない状況でデバッグをしていた。
いくらソースコードを見ても間違ってるように思えなかったので、寝起きにすっきりした頭で、クリーンビルドして実行したらすんなり動いた。
これで1日ぐらい潰したような。
日をまたぐと忘れるので公式アナウンス推奨のシンボリックリンク作成して試すようにした
・gdbが使いにくい
mingwのgdbだとエラーで止まってくれない
gdbでリダイレクトをするとエラーで止まってくれない
gdb上でリダイレクトありでgoコマンドを実行すると空白をひたすら送り続けるらしく、持ち時間0、秒読み0で探索が動いてしまう
これも1,2日ぐらい無駄にした気がする。とくに最後のやつがひどい。
・最適化ビルド
PGOやるにはsrcの下にシンボリックリンクを作るのが公式見解だった
詳しくは前のエントリ参照
・大樹の枝(配布版)との比較
設定
4コア、3秒(実質2.5秒)、ハッシュ2GB、先読み無し
NPS,5%~10%増し
探索深さ、0~-2(中盤妙にパフォーマンスが悪くなる場合がある)
というよくわからない状況になった。
ハッシュがヒットしているとカウントしないはずなのだが、探索深さが浅いのに数が多いというよくわからない状況になっている。
探索深さが2手浅いのが結構致命的で勝率は壊滅的だった。(ちょっと試した感じだとR200ぐらい落ちた)
本来なら8コアで伸びがあることを証明したいところだが、4コアのマシンしか持っていないので試せていない。
その後、あんまりひどいので探索周りを少しいじってたら、4コアでなんとなく互角っぽいLazy SMPバージョンが出来た(かもしれない)。探索深さ自体は変わっていないので、勝率は悪いはずだが、本家に存在する「4コア3秒のときに10局に1回ぐらい発生する中終盤で変な指し手を指すバグっぽい挙動(後述)」が改善された気がする(あくまでも「気がする」だけでちゃんと検証したわけではない)
・「4コア3秒のときに10局に1回ぐらい発生する中終盤で変な指し手を指すバグっぽい挙動」
割りとそれなりの頻度で、敗着っぽいのをいきなり指してしまう現象。
4コア3秒で指し手の候補が3つぐらい出てくるとき(Fail-Low連発してるとき?)に
0~2秒:3つぐらいの手で迷う
2~3秒:よりにもよって悪そうな手(無理攻め?)でロックされる
というのが、それなりの頻度である気がする。
電王トーナメントとかだと持ち時間制度なので、FailLowが発生したら持ち時間が伸びて解消されてると思うのだが、4コア1手3秒固定でやってると10局に1回ぐらいの頻度で発生しているように思う。(要出典)
・結論
すでにYBWCを実装している人は、電王トーナメントのような4コア前提ならやる意味は無い。
しかしマルチスレッド化をこれから実装する人はまずはLazySMPで実装してしまうのは良い方法だと思う。
コメント 0