TadaoYamaokaの開発日記

個人開発しているスマホアプリや将棋AIの開発ネタを中心に書いていきます。

Qugiyのビット演算を試す その2

昨日香車の利きと、飛車の縦方向の利き、歩の駒打ちについて、Qugiyのアピール文章のビット演算を実装して、速度を測定を行ったが効果がないことがわかった。

今回は、飛車と角の利きのビット演算を実装して、測定を行った。

飛車と角の利き

変更前

ZEN2を除いてCPUがBMI2に対応している場合はPEXTを使用し、ZEN2の場合はMagic Bitboardを使用している。
Magic Bitboardの解説は、やねうら王のブログを参照

変更後

Qugiyのアピール文章2の、飛車と角の利きのビット演算を実装した。
解説は、やねうら王のブログを参照
やねうら王ではBitboardのメソッドとして実装されており、非常に分かりやすかったので、流用させてもらった(感謝)。
Aperyの香車の利きテーブルの初期化処理は、飛車の利きを利用しており、飛車の利きのビット演算版では縦方向には香車の利きを利用しているため、作り直した。

doMoveでのcheckersBBの更新処理で、横方向の飛車の利きに、縦方向も合わせて利きを計算している処理は、横方向のみにできるようになったため、変更した。
やねうら王では別の方法で実装されていたが、修正が多くなるので、rookAttackRankを利用した。

case DirecRank:
    st_->checkersBB |= attacksFrom<Rook>(ksq) & bbOf(Rook, Dragon, us);

から

case DirecRank:
    st_->checkersBB |= rookAttackRank(ksq, occupiedBB()) & bbOf(Rook, Dragon, us);

に変更。

速度測定

香車の利きと飛車の縦方向の利きを変更したもので、変更前後のNPSを測定した。
floodgateからサンプリングした100局面を1秒思考した際のNPSを10回測定して平均を算出した。

GPU1枚(RTX3090)、Core i9 2スレッド
変更前 変更後 変更後/変更前
平均 29154 29074 99.6%
中央値 30302 30343 100.1%
最小値 18150 17386 95.8%
最大値 31735 31769 101.8%

平均値、中央値、最大値はほぼ変わらず誤差の範囲である。
最小値は低下している。
PEXTに対応したintelのCPUでは、速度改善の効果がないと判断してよさそうだ。

GPU8枚(A100)、ZEN2 4スレッド
変更前 変更後 変更後/変更前
平均 284701 287216 101.0%
中央値 287675 290034 100.9%
最小値 221218 230250 97.3%
最大値 335950 329870 106.2%

8GPU、ZEN2 4スレッドだと、平均値、中央値、最大値で速度が上がっている。
平均で1%程度の向上が確認できた。
変更後/変更前の最小値で下がっているのが気になるが、値の方の最小値は上がっているので、特定の局面で少し下がる場合があっても影響は少ないと考える。

まとめ

飛車と角の利きについてQugiyのビット演算を実装して、変更前後の速度を測定した。
結果、PEXTが使用できるintelのCPUでは速度は変わらず、ZEN2のCPUでは平均で1%NPSが向上することがわかった。

昨日の測定で効果のなかった香車の利きと、飛車の縦方向の利き、歩の駒打ちについては取り込まず、飛車と角の利きについてはmasterに取り込む予定である。