Coelacanth's Dream

AMD GPU 用のモニタリングツールを作り始めてから 1年が経ってた

タイトル通り amdgpu_top を作り始めてから 1年が経っていたため、実装した機能などを振り返ってみる。

GUI モード

v0.1.4 で GUI モードを追加した。GUI クレートには emilk/egui を用いている。
egui を選んだ理由としては、レイアウト用のテンプレートファイルを必要とせず、レイアウトの構築が Rust ソースコードだけで完結し、サンプルも分かりやすかったからだ。
また、これは使い始めてから気付いたが egui にはプロット用の機能もあり、モニタリングツールを作る上で相性は最高だった。
GUI モードを追加した切っ掛けは、TUI モードよりずっと多くの情報を一画面に表示するモードが必要と考えたことだ。
amdgpu_top には TUI モードの他にダンプ機能 (--dump) があり、それで GPU 情報の確認ができるのだが、正直 --help や README.md で利用可能なオプションを調べ、実際に確かめる人は少数だと思ってる。

GUI モードの欠点としてはバイナリサイズが大きくなることで、GUI モードを有効にしてビルドすると 13MiB 近く増える。
とはいえ他の GUI クレートを用いて大量の動的ライブラリへの依存を追加するよりは良い、かもしれない。

GUI モードには cargo-i18nFluent を用いた多言語対応も実装している。
これは誰かから要望があった訳ではなく、Rust における多言語対応を経験してみたくて実装した。
現状日本語は一部の説明のみを翻訳している。AMD GPU 独自の用語や単位などは変に翻訳するよりそのまま表示した方が分かりやすいと思っている。

SMI モード

SMI モードは複数の GPU を同時にモニタリングするために追加した。TUI モードも GUI モードも一つの画面に一つの GPU の情報を表示するのが限界だと思っている。それだけ AMDGPU ドライバーがユーザースペースに公開している情報は多い。
複数の dGPU を搭載可能な環境は持っていないが、APU (Ryzen 5 5600G) と dGPU (Radeon RX 6600) で一応検証可能なのは良かった。
レイアウトは rocm-smi, amd-smi より nvidia-smi の方に寄せてある。

amdgpu_top smi

自分が一番よく使っているのは SMI モードで次に TUI モード。それらのモードはターミナルから起動した場合は新規ウィンドウを作成しないため画面上の変化が小さく、知りたい情報をすぐに確かめられるからだ。
SMI モードは主に必要とする情報を詰め込んでおり、機能的な部分も気に入っている。

JSON モード

他のスクリプトやアプリケーションから利用するケースを想定して JSON モードも追加した。
最初は intel_gpu_top と同様、stdout に JSON 形式で情報を出力し続けるだけだったが、後から出力回数を指定可能にしたり、繰り返し amdgpu_top を呼び出さなくても済むように FIFO (名前付きパイプ) を作成する機能を追加した。
JSON 形式の出力自体は serde_json のおかげで簡単だった。

バージョン

現在 amdgpu_top の最新リリースは v0.8.2 となっていて、そこから細かい修正や機能追加がたまってきたため、近くに v0.8.3v0.9.0 をリリースするつもりでいる。
バージョンについては、GUI や SMI モードの追加といった大きな変更があったのにパッチバージョンの更新を続けた結果 v0.1.11 まで続いてしまったことを反省して、ある程度新機能と言えるものを追加したらマイナーバージョンを更新するようになった。
v1.0.0 のリリース予定は現状全くない。AMDGPU ドライバー側の更新や機能追加に合わせて amdgpu_top を更新する部分もあるため、どこを v1.0.0 とするかは難しいからだ。
ロードマップも無く、今後追加したい機能も特に考えていない。
強いて言えば、AMD XDNA, Ryzen AI, NPU, IPU……どう呼ぶのが良いのか分からないが、まあそういったものの対応をぼんやりと考えてはいる。
一応 Windows では NPU のモニタリング機能があるため可能だとは思うが、Linux 環境ではまだそのインターフェイスは公開されていない。xdna-driver が公開されてからまだ日が浅いのもあるだろう。xdna-driver を試すことのできる環境を持っていないため検証できていないが、ドライバーを読むに消費電力の表示には対応しているようだ。1
次世代の APU (SMU v14.0.0) であれば gpu_metrics に IPU の情報が含まれており、column ごとのIPU の使用率 (最大 8-columns) やリード/ライトの平均使用帯域、IPU 全体の消費電力、IPU の動作クロックをそこから取得できる。2

それ以外にも機能追加の要望があって、かつ可能なものであれば対応するつもりではいる。 ただオーバークロック関連の機能は追加するつもりはない。そうしたツールの方が需要も人気も強いらしいが、自分は amdgpu_top をあくまでもモニタリングツールとして開発している。
まあモニタリングツールとしても既存の radeontopnvtop の人気が根強く、amdgpu_top が使われている場面を見る機会は少ないが。

だが radeontop は作者が最近の AMD GPU 向けに更新する気はないことを明言しており3、最新のコミットは一年前に受け入れた PR のものとなっている。

nvtop は開発が続けられており、対応するデバイスの種類が増え、今では AMD, Intel, NVIDIA に加え、Qualcomm, Apple, Huawei Ascend (NPU) もサポートしているらしい。
しかしそれら全てを検証できる環境は無い。ベンダーの異なるデバイスを複数サポートするモニタリングツールの必要性は分かるが、作者の負担が増えていくという点で不安を覚える。
時々 AMD GPU 関連の issue を勝手に手伝ってはいるものの、作者の Syllo 氏は忙しいのか数ヶ月ごとに返信が来るような状態である。

amdgpu_top を開発する中で まともに モニタリングするためには、部分的に特定の GPU/APU や世代に向けたコードを書かなければならないことを知った。
例えばある GPU/APU は GPU使用率を常に 100% として返すとか、ある世代からはメディアエンジンへのエンコード/デコードキューが統合された関係でそれぞれの使用率を取得できないため、その世代に対しては使用率の計算方法と表示を変えなければならないとか。
他には、PCIe 使用帯域を取得するのに pcie_bw sysfs が使えるが、これは AMDGPU ドライバー側でパフォーマンスカウンターを用いた計測を行い、そこで msleep(1000) を使うため、そのまま読み取ろうとすると 1秒間スレッドが停止する。そのため別スレッドで読み取る必要がある、とか。

そうして得た知見は他のモニタリングツールで発生している問題の解決に役立つはずだ。
今後別のモニタリングツールを誰かが開発するとしても、検証用に比較できるものが必要だろう。

とはいえ結局の所、そうした大層な理由よりも、amdgpu_top の一番のユーザーは自分自身というドックフーディングであることが開発を続けている一番の理由なのだが。