Coelacanth's Dream

RadeonSIドライバーに FMA32命令を強制するオプションが追加

これまでに取り上げた AMDGPU における FMA、MAD命令の違いが関係する話。
AMD GPU の世代における FMA、MAD 命令の微妙な仕様と違い | Coelacanth’s Dream AMD GPU の世代における FMA、MAD 命令の微妙な仕様と違い Part2 | Coelacanth’s Dream

タイトルの通り、RadeonSI (OpenGL) ドライバーに FMA32命令を強制的に使用するオプションが追加された。

Index

性能

段階を踏んで解説すると、AMD GPU では GFX6-8 の世代だと FMA、MAD命令の処理性能に違いがあり、FMA命令は MAD命令の 1/4 という性能だった。
GFX9 (Vega) の世代からは FMA命令が MAD命令と同等の処理性能となり、GFX10.3 (RDNA 2) の世代では MAD命令が取り除かれ、FMA命令に置き換えられた。
ドライバー、シェーダーコンパイラでは、GFX6-8 では MAD命令を、GFX9-10 ではどちらでも性能は変わらないが MAD命令を、GFX10.3 では FMA命令を使う形で対応していた。GFX10.3 の場合、MAD命令だと MUL+ADD に分けて処理するため、逆に遅くなる。

一応、GFX6-8 世代でも倍精度演算への対応が強化されている一部 GPU では、FMA、MAD命令の性能が同等となっており、Tahiti (gfx600), Hawaii (gfx702), Hawaii Pro (gfx701), Carrizo (gfx801) が該当するが、ドライバーとしては対応を簡潔にするために、上のような形にしていると思われる。

       /*        |---------------------------------- Performance & Availability --------------------------------|
        *        |MAD/MAC/MADAK/MADMK|MAD_LEGACY|MAC_LEGACY|    FMA     |FMAC/FMAAK/FMAMK|FMA_LEGACY|PK_FMA_F16,|Best choice
        * Arch   |    F32,F16,F64    | F32,F16  | F32,F16  |F32,F16,F64 |    F32,F16     | F32,F16  |PK_FMAC_F16|F16,F32,F64
        * ------------------------------------------------------------------------------------------------------------------
        * gfx6,7 |     1 , - , -     |  1 , -   |  1 , -   |1/4, - ,1/16|     - , -      |  - , -   |   - , -   | - ,MAD,FMA
        * gfx8   |     1 , 1 , -     |  1 , -   |  - , -   |1/4, 1 ,1/16|     - , -      |  - , -   |   - , -   |MAD,MAD,FMA
        * gfx9   |     1 ,1|0, -     |  1 , -   |  - , -   | 1 , 1 ,1/16|    0|1, -      |  - , 1   |   2 , -   |FMA,MAD,FMA
        * gfx10  |     1 , - , -     |  1 , -   |  1 , -   | 1 , 1 ,1/16|     1 , 1      |  - , -   |   2 , 2   |FMA,MAD,FMA
        * gfx10.3|     - , - , -     |  - , -   |  - , -   | 1 , 1 ,1/16|     1 , 1      |  1 , -   |   2 , 2   |  all FMA
        *
        * Tahiti, Hawaii, Carrizo, Vega20: FMA_F32 is full rate, FMA_F64 is 1/4
        * gfx9 supports MAD_F16 only on Vega10, Raven, Raven2, Renoir.
        * gfx9 supports FMAC_F32 only on Vega20, but doesn't support FMAAK and FMAMK.
        *
        * gfx8 prefers MAD for F16 because of MAC/MADAK/MADMK.
        * gfx9 and newer prefer FMA for F16 because of the packed instruction.
        * gfx10 and older prefer MAD for F32 because of the legacy instruction.
        */

丸め誤差 ULP

AMD GPU における FMA、MAD命令の性能以外での違いには計算精度、丸め誤差 ULP (Unit in the Last Place) の違いが挙げられる。
FMA命令では 0.5ULP、MAD命令では 1ULP が保証されており、FMA命令の方が精度が高くなっている。
今回 FMA命令を強制するオプションが追加されたのは、この計算精度のためで、該当マージリークエストによれば、精度の違いにより結果の最後のビットが異なることがある。
シミュレーションによる試作、試験のポストプロセッシングツール META では精度の違いが赤いブロックとして表れ、FMA、MAD命令で目に見える結果も異なってしまう。

RadeonSIドライバーでは、FMA命令を強制するオプション (radeonsi_force_use_fma32) が METAアプリケーションに対してはデフォルトで有効化される。
またオプションの影響を受ける AMDGPU の世代は、FMA、MAD命令で性能が変わらない GFX9-10 のみで、性能に差が大きくある GFX6-8 ではそのまま MAD命令が使われる。

 +   /* fma32 is too slow for gpu < gfx9, so force it only when gpu >= gfx9 */
 +   bool force_fma32 =
 +      sscreen->info.chip_class >= GFX9 && sscreen->options.force_use_fma32;
 +

参考リンク