Coelacanth's Dream

【シーラカンスノート】 シェーダーコンパイラへの将来的な機械学習、深層学習の活用、RADV/ACO NGG 再度有効化 【2020/10/21】

Index

機械学習、深層学習の活用

AMD がオープンソースで提供する AMDVLK において、Vulkan API のコマンドを PAL (Platform Abstraction Library) のコマンドに変換するレイヤー部 XGL将来的に 実装される であろう 機能の説明が記述されていた。
あくまで説明のみであり、それに自分の推測を足したものであることを留意して頂きたい。

Waveサイズの選択

AMDGPU ではスレッドの塊となる Wave 単位で命令を発行するが、その Wave のサイズに RDNAアーキテクチャ では Wave64 (64スレッド) と Wave32 (32スレッド) の両方に対応している。
どちらの Waveサイズにも利点があり、Wave64 はベクタレジスタの粒度が Wave32時の半分になるため、メモリのフットプリントが小さくなり、また多くのスレッドが同じ CUで実行されるため、L0キャッシュにヒットしやすくなるというのがある。1
Wave32 では分岐等の制御を Wave ごとに処理でき (Wave64 でもそうだが、スレッド数に対しての制御処理は Wave32 の半分の回数となる)、
ベクタレジスタの粒度は Wave64時より大きくなるが、Waveサイズが小さいことで処理の完了が速く、データにアクセスするのに必要なリソースは少なくなり、レジスタの解放を速く行なえるという利点がある。2

ある処理に対して、どちらの Waveサイズが適しているかはそれぞれ異なるが、RadeonSI (OpenGL) ドライバーでは現在どのシェーダーステージも Wave64 で実行するようになっている。
RadeonSI ドライバーでは RDNA GPU も Wave64モードで各シェーダーを実行するように | Coelacanth’s Dream RDNAアーキテクチャ の資料では、元は Pixel Shader は Wave64、Vertex/Tess/Geomtory Shader は Wave32 としていた。
検証の結果 Wave64 の方が良い、となったと思われるが、今後も最適化として Waveサイズの変更が行なわれることが考えられる。

そうした中で XGL から見つかった機能は、ドライバーのコード中に記述されたデフォルトの Waveサイズを選ぶのではなく、機械学習モデルを用いてシェーダーステージごとに最適な Waveサイズを決定するというものである。

           {
             "Name": "MlModelForWaveSizeOff",
             "Value": 0,
             "Description": "Wave size selection is determined by WaveSize enum."
           },
           {
             "Name": "MlModelForWaveSizePhase1",
             "Value": 1,
             "Description": "Enabled wave size selection is post-compile using Machine Learning."
           },
           {
             "Name": "MlModelForWaveSizePhase2",
             "Value": 2,
             "Description": "Enabled wave size selection is pre-compile using Deep Learning."
           }
         ],
         "Name": "WaveSizeDecision"
       },
       "Description": "Enable a machine learning model to optimally choose Wave64 or Wave32 instead of relying on per shader stage defaults.",

これが実際に実装されれば、検証してからコード内の値を変更するという手間を減らせ、2つの Waveサイズに対応する RDNAアーキテクチャ の特徴をより性能向上へと活かせるようになるだろう。
上で将来的な機能と書いたように、現在では未実装。

NGGカリングに発見的手法を

先日RadeonSI (OpenGL) ドライバーと RDNA /GFX10 世代の Radeon Pro カード、または RDNA 2 /GFX10.3 世代の dGPU との組み合わせでは、デフォルトで有効とするようになった NGGカリングだが、
それに機械学習モデルによる発見的手法を適用するという機能の説明が見つかった。

     {
       "Description": "Enable the use of SC heuristic machine learning culling for NGG culling, culling is enabled for Gfx10.3 by default.",
       "Tags": [
         "Optimization"
       ],
       "Defaults": {
         "Default": false
       },
       "Scope": "Driver",
       "Type": "bool",
       "VariableName": "enableMlHeuristicCulling",
       "Name": "EnableMlHeuristicCulling"
     },

発見的手法 (heuristic, ヒューリスティック) には、アルゴリズムによる手法よりも速く答えを導き出せるという利点があるが、精度が低いという欠点がある。
だがその精度の低さも、グラフィクス処理では画面に映し出される絵がほんの少し変わる程度となり、あまり重要視しなくて済むと思われる。

また、この説明が追加されたのは 2020/09/27 のコミットだが3、その時から NGGカリングを RDNA 2 /GFX10.3 世代でデフォルトに有効にすることは決まっていたようだ。
そのことが説明にあることから、RDNA 2 /GFX10.3 世代での実装が考えられるが、あくまでも個人の推測である。

RADV/ACO NGG 再度有効化

この前、RADV/ACO NGG を有効にしてテストを行なうとランダムで動作が停止するため、一旦無効化することになったと伝えたが、
その件で AMD の開発者と回避方法を共有したらしく、再度有効化されることとなった。
aco: A few minor improvements to NGG GS (!7232) · Merge Requests · Mesa / mesa · GitLab 出力するプリミティブ数が 0 の場合は、面積の無い三角形を出力する処理を追加することで GPU のハングを回避できるそうだ。
また AMD によると、この回避策は常に必要とのこと。AMD もドライバー開発の中で同じ障害にぶつかったのかもしれない。