やねうら王、100MB程度(登録局面数70万局面程度)の定跡ファイルを読み込むのに私の開発用のノーパソであるSurface Pro 6で16秒ぐらいかかってたんですけど、さすがに我慢ならなくてチューニングしました。
https://github.com/yaneurao/YaneuraOu/commit/0d898faff3784cb460cb0584963e626b21098963
読み込み部分、大改造になったので何かエンバグしてるかもです。(´ω`)
何かあればすぐに修正しますのでこの記事のコメント欄などで教えてください。
遅かった原因は、まずC++のifstreamが遅いということです。ifstreamの仕様、ごちゃごちゃ色んなものを盛り込んであるので、Cのfopen~freadと比較すると5倍ぐらい遅くなっています。そんなわけでifstream使うのやめて、fopenでバイナリオープンして fread でバイナリとして読み込んで自前でparseするようにしました。
…というか、それに似た処理、25年ぐらい前に一度書いた記憶があるんですけど、何故に2020年にもなってこんなことをしないといけないのでしょうか。本当、C++みたいなクソ言語は早く滅んだほうがいいと思います。
それから、istringstreamもがっつり遅いので、これも自前でparseするように書き換えました。
その二点を高速化することで定跡読み込みが4倍ぐらい速くなりました。
あとはunorderedmapまわりで定跡読み込み時の40%ぐらいの時間を消費しています。これは安易にunorderedmapを使ったのがあまり良くなかったのだと思います。この部分の高速化もできなくはないですが、今回は見送ります。
とりあえず、500MBぐらいの定跡(登録局面数350万局面程度)が20秒ぐらいで読み込めるようになったので、それくらいの規模までの定跡ファイルならぎりぎり実用の範囲かなと。
まあ、どうしても時間がかかるようならBookOnTheFlyという定跡をメモリに読み込まずに、probe(定跡にhitするかを調べる)のときにテキストファイルを二分探索するというオプションがあるので、それをオンにして運用すれば良いと思います。
探索部いつも公開していただきありがとうございます。やねさんもうフリーでの評価関数の公開はされない感じでしょうか?
それは気が向いたらまた公開します(`・ω・´)b
『将棋神やねうら王』との兼ね合いでどれくらいのところまでフリーで公開するのか難しいです。
昔sfenパースの高速化にチャレンジしたことがあったけど、ガチでやるならバイト単位でパースするしかないですね。
https://github.com/tibigame/YaneuraOu_random-sfen/blob/master/source/position_sfen_fast.cpp
うおー!それ、本気(ガチ)の奴じゃないですか…。
今、定跡データをいじくるプログラムを書いているのですが、定跡の評価値は、評価値が高い順に並んでいなくても、バグりませんよね?
(正直これ以上コードは書きたくないので…)
例えばこのような感じ↓
sfen・・・・(長くなるので省略)
9f9e 7a7b 150 32 2
1g1f 1c1d 200 32 1
8f9e 1c1d 50 32 1
バグ?の報告?です。V4.89です。
①YaneuraOu_NNUE_learn_sse42.exe hash 2048 , Threads 4 , bookfile no_book , MultiPv 4 , makebook think G0.sfen standard_book.db startmoves 15 moves 16 depth 30 , quit
YaneuraOu_NNUE_learn_sse42.exe hash 2048 , Threads 4 , bookfile no_book , MultiPv 4 , makebook think G0.sfen standard_book.db startmoves 17 moves 18 depth 30 , quit
というバッチファイルを組みました。(見づらくて申し訳ないです。)
②一つ目のコマンド(15手目から16手目までの思考)が完了し、二つ目のコマンド(17手目から18手目までの思考)が半分ぐらい進んでいるところで定跡の出来を確認するべく、バッチファイルを一度閉じました。
③確認し終わったら、standard_book.db-25.dbみたいな感じでセーブされている一番最近セーブされた定跡をstandard_book.dbにリネームして、一つ目のコマンドを消さないで、もう一度バッチファイルを実行しました。
そうすると、終わった(全て思考しきった)はずの、15手目から16手目までの所で、total 39 nodeと表示されました。(これまでにもありましたが、あまり気にしていませんでした。)(また、私の記憶では、この現象は、V4.89になってからです。)
ご報告、ありがとうございます。調査しますです(`・ω・´)ゞ
遅くなりまして申し訳ありません。本日このあとのcommitで修正されるはずです。
IgnoreBookPlyオプションがtrueのとき(デフォルトでtrueに変更された)に、sfenの末尾の数字(ply)を削ってメモリに読み込むため、makebook thinkで思考対象とする局面を剪定するときに、そこにhitしないというバグでした。(´ω`)
あとIgnoreBookPly true だと、定跡ファイルのplyのところ0になりますので、この挙動が嫌ならば、IgnoreBookPly falseで定跡を掘るのもありかと思います…が、最近はply無視するほうが主流になりつつあるので(角換わりで千日手模様で打開することが多いようで)、まあ、いいかと…。
あと、Hashオプションはなくなりましたので、USI_Hashに変更してください。
いえいえ、こちらこそ、やねうら王の開発に少しでも貢献できて光栄です(´ω`)
後、よくよく見たら私も返信遅かったですね( ´艸`)
申し訳ありません。