個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。自己対局でノードの再利用しないようにしたが、NNの計算結果は再利用した方が効率がよいため、キャッシュの仕組みを導入したい。並列で実行しているゲームすべてについて1ゲーム分のNNの結果を保持するにはメモリ容量が不足するため、使用されなくなった局面(古い手番で探索した局面)を削除する仕組みが必要になる。その仕組みとして、単純な方法としては、ゲームごとに開始局面からの手数を記録しておき、局面の探索開始前に古い手数の局面を削除するようなことが考えられる。一部のエントリを削除する場合、エントリの線形探索やハッシュエントリの再配置が必要になるため効率が良くない。Cacheという仕組みがある。オペレーティングシステムの教科書とかでよく出てくる。Cacheの実装には、検索すればサンプルコードがいくつも出てくる。ほとんどは、mapかunordered_mapと、リンクリストを使って実装されている。boostでもlru_cache.hppに実装されている。並列実行する自己対局で使用するには、スレッドセーフな実装が必要になる。Cacheが使用されている。スレッドセーフで、ゾブリストハッシュと組み合わせて使用できるように実装されている。テンプレートで汎用的に実装されているため、将棋AIでもそのまま流用できそうなので、利用させてもらうことにする。Cacheは以下のようにして使用する。Zeroのcache.hを流用したソースLRUキャッシュを作成するには、LruCacheのテンプレート引数の1つ目にキーの型、2つ目に格納する値の型を指定する。コンストラクタの引数にはキャッシュサイズを指定する。Insertメソッドにキーと値を設定して、エントリを追加する。値は、unique_ptrにする必要がある。値を検索して使用する場合は、LookupAndPinメソッドで値を取り出して使用し、使用が終わった後Unpinで値を戻す。LruCacheLockを使うとスコープ範囲内で、LookupAndPinとUnpinの呼び出しを自動化できる。上記コードの実行結果は以下のようになる。9キャッシュサイズが8で、10エントリを追加しており、古いエントリから削除されていることが確認できる。»プロフィールid:TadaoYamaokaスマホアプリ開発とディープラーニングを使った将棋ソフトの開発を行っています。)はてなブログをはじめよう!TadaoYamaokaさんは、はてなブログを使っています。ブログを報告する引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。