これまでに取り上げた 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; +