以前のdlshogiは、マルチGPUで動かした場合、4GPUまでは線形にNPSが伸びるがそれ以上GPUを増やしてもNPSが伸びなかった。
ハッシュテーブルのロックにボトルネックがありそうだ思っていたので、今回ロックの範囲を修正してマルチGPUでの性能を改善した。
ロックの範囲
dlshogiは、ハッシュテーブルをハッシュキーの番地から空きエントリをインデックスをインクリメントしながら線形に探索する方法で実装している。
空きエントリを探す処理は複数スレッドで排他制御する必要がある。
今までは、空きエントリの探索とエントリの初期化をロックの範囲としていた。
エントリの初期化には、ノードの合法手を設定する処理も含んでいた。
合法手の生成はある程度時間のかかる処理なので、この部分をロック範囲に含めないように修正した。
初期化前に他のスレッドが当該ノードを参照する場合があるため、初期化済みか確認するようにした。
以前の性能
修正前にGPUを増やした場合のNPSは以下の通り。
GPUにTesla V100×8を使用し、Ubuntuで計測した。
floodgateの棋譜からランダムにサンプリングした100局面を秒読み5秒で探索した場合の、平均、最大、最小のNPSをプロットした。
測定用コード:https://github.com/TadaoYamaoka/DeepLearningShogi/blob/master/utils/benchmark.py
4GPUまでは、ほぼ線形に伸びて、5GPUからは伸びが少なくなっている。
なお、dlshogiでは末端ノードで5手の詰み探索を行っているため、終盤の王手が多い局面ではNPSが落ちるため、最大と最小のNPSにはかなりの開きがある。
チューニング
GPU数、GPUあたりのスレッド数、バッチサイズを変えてNPSを測定した。
※横軸:先頭の数値がGPU数(なしは8)、bxxxがバッチサイズ(デフォルトは128)、thxがGPUあたりのスレッド数
最大、平均のNPSは、GPU数:8、スレッド数:3、バッチサイズ:128で最大となっている。
最小のNPSでは、GPU数:7、スレッド数:2、バッチサイズ:128で最大となっている。
NPS最大となる局面では195,703と、ほぼ20万NPSに達している。
末端ノードでの詰み探索を外せばもっとNPSが上がるが、詰み探索があった方が勝率が高くなる。
Windowsでの性能
測定環境の都合で、Ubuntu(Linux)で測定したが、Windowsではバッチサイズを増やした方が性能が上がる傾向がある。
上記のLinuxでの測定と異なるGPU(2080Ti)1枚、4コアCPUでの、Windowsでの測定結果は以下の通り。
わずかな違いだが、平均のNPSはバッチサイズ176の場合が一番高い。
GPU1枚での比較しかデータがないが、LinuxよりWindowsの方が性能がよい。
8GPUでも性能がでるようになったので、世界コンピュータ選手権のオンライン大会は8GPUで出たいと思っている。
NPSが低い局面ではGPUを増やしてもNPS伸びていないので、もう少し原因を探ってみたい。