GA将?開発日記~王理のその先へ~

ネタ勢最強を目指して絶賛開発中。

短期目標

 当面の方針は「ひたすら高速化する」ですが、今まで書いてなかった事も含めてまとめときます。

 まず、やる予定の事。括弧内は速度向上率の目標値。

  1. マルチスレッド化 (x6)
  2. 評価関数の再実装 (x3)
  3. 二駒の相対位置関係のチューニング (x1.2)
  4. ログ出力まわりの整理 (x1.05も行かないかも)
  5. ルートノードでの枝刈り(x4位は行って欲しい)
  6. 探索ノード数の削減 (x1.5)

 以下、項目ごとに。

マルチスレッド化

 方策がソフトマックスなので「対局中の局面から深さ1の全ノードの正確な評価値を計算する」という処理があります。

 で、各ノードの評価値の計算(探索)は完全に独立しているので、この部分で並列化の予定。

 CPUがCore i7なので、4コア8スレッドで速度向上が6倍あたりが限界だと予測。ただ、これは(計算結果に影響を与えない)純粋な高速化なので、ここで出来るだけ速度を稼ぐ。

評価関数の再実装

 現在はstd::mapを使っていて遅いので、局面評価時はmapを使わない様に修正。

 パラメータ修正時はmapが必要だけど、そっちはボトルネックにならないので無視。

 マルチスレッド化と同じく、純粋な高速化。ここでも速度を稼ぐ。

二駒の相対位置関係のチューニング

 相対位置関係は先後や左右を反転した関係が複数あって、これを特定の一つの関係に変換してから局面評価に使ってます。

 で、この変換処理はif文が入れ子になった、いかにも遅そうなコードなので、ここをチューニングします。

 変換処理自体は単純に表を見るだけでも実現可能なので、使用するメモリの量さえ足りるなら表引きで実装予定。

 純粋な高速化だけど、大幅な速度向上は多分無理。優先度低い。

ログ出力まわりの整理

 ログ出力用の関数があって、出力するメッセージのログレベルを設定ファイルの閾値と比較して、出力の有無を決めている部分があります。

 が、マクロを使えば出力しない部分はザクッと消せるので、そうしようかと検討中。

 ひたすら置換するだけで実装コストは低いけど、その分リターンも低い。

ルートノードでの枝刈り

 上で書いた「対局中の局面から深さ1の全ノードの正確な評価値を計算する」という処理に手を加えようかと検討中。

 全合法手をウィンドウ[-∞,+∞]で探索すると無駄なので、[仮の最善手の評価値 - マージン,+∞]にして高速化出来ないかと考えてます。

 ソフトマックスだと評価値が高いほど高確率で選択しますが、私が今使ってる温度の設定だと、評価値が0.2低いと選択確率が480万分の1になるので、マージン0.2にしとけば実用上問題ない範囲で枝刈り可能…なハズ。

 これは純粋な高速化ではないので、実際にやってみながら出たとこ勝負で何とかします。

 …マージン0.15だと10万分の1・・・そこまでマージン削ると危険かなぁ・・・・・・

// 以下、追記

探索ノード数の削減

 基本を忘れてましたが、探索ルーチンが今のもので良いのかも検討しないといけません。

 とりあえずは序盤〜終盤でのノード数やmpn*1の変化を調べて、後はその結果次第ですね。

 ただ、実際のところムーブオーダリングの改善ぐらいしか出来る事は無いので、やったとしてもあまり成果は出ないかも。

*1:Move Per Nodeの略。マイムーブ西村さん命名。平均何手目でβカットが起きているかを示す値。