TadaoYamaokaの日記

山岡忠夫Homeで公開しているプログラムの開発ネタを中心に書いていきます。

タスクマネージャーのメモリ使用量

将棋AIの学習のためにGPUを増やしたところ、まったく速度が上がらないどころか低下するという事象が起きて、ここ数日原因を調べていました。
メモリスワップが起きていたことが原因で、わかってしまえば単純な話でしたが、Windowsのタスクマネージャーの仕様の理解が不足していたため、数日悩むことになりました。

物理メモリを食いつぶしていたので、Windows 10のタスクマネージャーの詳細タブでプロセスのメモリ使用量を見ると、プロセスを起動してから、メモリ(プライベートワーキングセット)の数字が徐々に上がっていたため、メモリリークを起こしているのではないかと疑いました。

プライベートワーキングセットとは

実は、タスクマネージャー表示されるメモリ(プライベートワーキングセット)は、プロセスに割りあてられたページの物理メモリのサイズを示しており、C++のnewで確保したメモリは、仮想メモリが割り当てられるだけで、実際にアクセスするまではOSに物理メモリが割り当てられないということが今回調べてわかりました。
詳しい人によっては、常識レベルの話で、自分も仮想メモリの動作は知識としては知っていたはずですが、タスクマネージャーの数値の意味を理解していませんでした。

なお、仮想メモリのサイズを見るにはタスクマネージャーで、列の選択で「コミット サイズ」を表示する必要があります。


f:id:TadaoYamaoka:20181121210733p:plain


ということで、徐々に上がる=メモリリークと勘違いしたため、コードを変えたりして原因を探してもリークしている箇所が見つからず数日時間を浪費しましたorz。
しかし、おかげでタスクマネージャーと仮想メモリについて理解が深まったので良いとします。

プログラムの改良

自己対局プログラムは、1つのGPUごとにエージェント複数割り当てて、それぞれのエージェントに別々のハッシュを割り当てていたので、メモリが大量に必要となる構成になっていました。
以前に、エージェントを全て別スレッドで動かしていたときの構成を引きずって、そのような構成になっていましたが、現在はシングルスレッドで直列に動かしているため、ハッシュを共有することで、メモリ使用量を減らすように修正しました。
メモリスワップが起こらないサイズに調整したことで、安定した速度で自己対局が行えるようになりました。