USIプロトコルでisready後の初期化に時間がかかる時にどうすれば良いのか?

最近はコンピュータ将棋用にメモリをたくさん搭載する人も珍しくはないが、64GB程度積んでいるとメモリの初期化に時間がわりとかかる。USIプロトコルでは時間のかかる初期化はGUI側から”isready”が送られてきたあとに行うことになっているが、ここで置換表のためのメモリをゼロ初期化すると少し困ったことになるのだ。

大きなメモリの初期化だとわりと時間がかかる。このときにGUI側が15秒以内にエンジン側から”readyok”が送られてこないとタイムアウトとなる処理になってたりすると、この時間を超過しかねない。古いCPU、古いメモリで(ゼロ初期化に時間がかかるのに)メモリを多く搭載しているとこの現象が起きやすい。

ShogiGUIにはタイムアウトが実装されていて、この現象についてユーザーからやねうら王側にレポートをいただくようになった。将棋神やねうら王のほうもUpdate2以降でタイムアウトを実装したのだが、これについてもタイムアウトになるとレポートをいただくことになった。(将棋所は、タイムアウトは実装されていなくてこの現象が起きない)

仕方ないので、エンジン側でメモリを初期化する時に定期的に空行を標準出力に(GUI側に)返すようにした。空行をkeepaliveの代わりに使おうという意図であり、ShogiGUIの作者がそのサポート掲示板でそうするようにしてくださいと返答していたからである。

しかし、どうもこれでは回避できない環境があるっぽい。

ゼロ初期化するのを高速化するためにThreadオプションで指定されたスレッド数で並列化してゼロ初期化するコードがStockfishの2018年後半ぐらいに追加された。やねうら王でもそれを導入している。そのせいか、すべてのスレッドがビジー状態で、通信用のスレッドがメッセージをGUI側に送れない(定期的にkeepaliveを送る用のスレッドの起動自体が追いついていない可能性もある)、もしくは、GUI側の通信スレッドもそれを受信できないようである。(エンジン側の通信スレッドのプライオリティを上げろという話もなくはないが、エンジン側はなるべく標準的なC++の機能だけでビルドできるようにしてあるため、環境依存となるAPIはあまり呼び出したくない)

そもそも、通信スレッドのプライオリティをいくら上げても無駄のような気もする。(実験はしていない)

Windows 10では、巨大なメモリを確保した段階では、そのメモリ空間は物理メモリに割当てがなされておらず、そこに初回にアクセスすることでpage faultが発生して、ハードウェア的な割り込みがかかり、そのハンドラで物理メモリが割当てられるような実装になっていると思うのだが、このハンドラの実行優先度が高く、この処理が連続して行われていると他のプログラム(スレッド等)にはほとんど実行のチャンスが巡ってこない可能性がある。(くどいようだが、実験はしていない。想像で書いている)

別の問題として2つのエンジンを対局のために同時に初期化するケースが考えられる。この場合もそれぞれのエンジンがエンジンオプション指定されたThread数で並列的にメモリのゼロ初期化を行うが、このThread数はCPUの論理コア数が指定されているのが普通であり、2つのエンジンなのでCPUの論理コア数の2倍のスレッド数のスレッドが動いている。この時点ですでにCPU的にはキャパオーバーなので、通信スレッドの優先度を上げたところでどうにもならない可能性が高い。

そんなわけで、GUI側はタイムアウト時間をユーザーが設定できるようにすべきだという結論になって、将棋神やねうら王のアップデートでタイムアウト時間を指定できるようにしたのだが、しかしよく考えてみると、一般ユーザーが”isready”のあと、応答を返さないようなエンジンを使うとは考えづらく、GUI側はタイムアウトなんか気にせず、いつまでも待っていれば良いのではないのか。エンジン開発者が何かバグを仕込んで、”isready”のあと応答を返さないことがあったとしても、その時は、GUI自体を×ボタンで閉じるなり、タスクマネージャーから終了させるなりすれば良いのではないのか。開発者なんだから、それくらいできるだろう。

というわけで、結論的には、GUI側にタイムアウト時間を設けるのはあまりよくない設計で、エンジン初期化中に「キャンセル」とか「中断」とかはできたほうが良いかも知れないが、まあ、それも上に書いた理由で、無くてもいいかなと思っている。

そんなわけで、やねうら王側にあった、別スレッドで定期的にkeepaliveを送る処理、この実装部のコードは近日中に削除しようと思う。

USIプロトコルでisready後の初期化に時間がかかる時にどうすれば良いのか?」への2件のフィードバック

  1. >> 初回にアクセスすることで

    wikipediaのトランスレーション・ルックアサイド・バッファあたりなのかな。よくわかりませんが

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です