コンピューティング、特にデジタル信号処理において、乗算累算(MAC)または乗算加算(MAD)演算は、2つの数値の積を計算し、その積をアキュムレータに加算する一般的なステップです。この演算を実行するハードウェアユニットは、乗算累算器(MACユニット)と呼ばれます。また、演算自体もMACまたはMAD演算と呼ばれることがよくあります。MAC演算は、アキュムレータを次のように変更します。
浮動小数点数の場合、2回の丸め(多くのDSPで一般的)または1回の丸めで実行されます。1回の丸めで実行される場合は、融合乗算加算(FMA)または融合乗算累算(FMAC )と呼ばれます。
現代のコンピュータには、組み合わせ論理で実装された乗算器、それに続く加算器、そして結果を格納する累算器レジスタで構成される専用のMACが搭載されている場合があります。レジスタの出力は加算器の1つの入力にフィードバックされるため、各クロックサイクルで乗算器の出力がレジスタに加算されます。組み合わせ乗算器は大量のロジックを必要としますが、初期のコンピュータで一般的だったシフトと加算の方法よりもはるかに高速に積を計算できます。パーシー・ラドゲートは、1909年の解析マシンで初めてMACを考案し、[ 1 ]、MACを除算(収束級数(1 + x)−1を介して逆数をシードとする乗算を使用)に初めて利用しました。MACユニットを搭載した最初の現代のプロセッサはデジタル信号プロセッサでしたが、この手法は現在では汎用プロセッサでも一般的に使用されています。[ 2 ] [ 3 ] [ 4 ] [ 5 ]
浮動小数点演算では
[編集]整数の場合、演算は通常正確です(2のべき乗を法として計算されます)。しかし、浮動小数点数にはある程度の数学的精度しかありません。つまり、デジタル浮動小数点演算は一般に結合法や分配法則に従っていません。(浮動小数点演算の§ 精度の問題を参照してください。)したがって、乗算と加算を2回の丸めで実行するか、1回の丸めで1回の演算(融合乗算と加算)で実行するかによって結果が異なります。IEEE 754-2008では、より正確な結果を得るために、1回の丸めで実行する必要があると規定されています。[ 6 ]
融合乗算と加算
[編集]融合乗算加算(FMAまたはfmadd)[ 7 ]は、浮動小数点乗算加算演算を1ステップ(融合演算)で実行し、1回の丸め処理を行います。つまり、非融合乗算加算では積b × cを計算し、それをNビットの有効ビットに丸め、その結果をaに加算し、再びNビットの有効ビットに丸めますが、融合乗算加算では式a + ( b × c )全体を完全な精度で計算し、最終結果をNビットの有効ビットに切り捨てます。
高速 FMA は、積の累積を伴う多くの計算を高速化し、精度を向上させることができます。
融合乗加算は通常、より正確な結果をもたらすと信頼できます。しかし、ウィリアム・カーンは、これを軽率に使用すると問題が発生する可能性があることを指摘しています。[ 8 ] x 2 − y 2 を(( x × x ) − y × y )と評価する場合(カーハンが提案した記法では、冗長な括弧によってコンパイラは最初に( x × x )項を丸めます)、融合乗加算を使用すると、最初の乗算で下位ビットが切り捨てられるため、 x = yであっても結果が負になる可能性があります。その結果、例えば結果の平方根を評価するとエラーが発生する可能性があります。
マイクロプロセッサ内に実装した場合、FMAは乗算と加算を繰り返すよりも高速です。しかし、IBM RS/6000のオリジナル設計に基づく標準的な産業用実装では、合計値を正しく計算するために2Nビットの加算器が必要です。[ 9 ]
この命令を組み込むことによるもう一つの利点は、除算(除算アルゴリズムを参照)と平方根(平方根の計算方法を参照)演算を効率的にソフトウェアで実装できるため、これらの演算に専用のハードウェアが必要なくなることです。[ 10 ]
ドット積命令
[編集]一部のマシンでは、複数の融合乗算加算演算を 1 つのステップに組み合わせます。たとえば、2 つの 128 ビットSIMDレジスタに対して 4 要素のドット積をa0×b0 + a1×b1 + a2×b2 + a3×b31 サイクルのスループットで実行します。
サポート
[編集]FMA 操作はIEEE 754-2008に含まれています。
C言語の1999年標準規格では、標準数学ライブラリ関数と、乗算と加算(浮動小数点式の縮約)の自動変換を通じてFMA演算をサポートしており、標準プラグマ( )によって明示的に有効化または無効化することができます。GCCおよびClang Cコンパイラは、FMA命令をサポートするプロセッサアーキテクチャでは、デフォルトでこのような変換を行います。前述のプラグマをサポートしていないGCCでは、[ 11 ]コマンドラインオプションによってグローバルに制御できます。[ 12 ]fma()#pragma STDC FP_CONTRACT-ffp-contract
融合乗算加算演算はIBM POWER1(1990)プロセッサで「融合乗算加算」として導入されましたが[ 13 ]、その後多くのプロセッサに追加されました。
- IBM POWER1 (1990)
- HP PA-8000 (1996) 以降
- 日立 SuperH SH-4 (1998)
- IBM z/Architecture (1998 年以降)
- SCE -東芝 エモーションエンジン(1999)
- インテルItanium (2001)
- STIセル(2006)
- 富士通 SPARC64 VI (2007) 以上
- (MIPS互換)Loongson -2F(2008)[ 14 ]
- RISC-V命令セット(2010)
- VFPv4 および/または NEONv2 を搭載した ARM プロセッサ:
- ARM Cortex-M4F (2010)
- STM32 Cortex-M33(VFMA動作)[ 15 ]
- ARM Cortex-A5 (2012)
- ARM Cortex-A7 (2013)
- ARM Cortex-A15 (2012)
- クアルコム・クレイト(2012)
- アップル A6 (2012)
- すべてのARMv8プロセッサ
- 富士通 A64FXには、「プレフィックス命令付き 4 オペランド FMA」が搭載されています。
- FMA3および/またはFMA4命令セットを備えたx86プロセッサ
- AMD Bulldozer (2011、FMA4 のみ)
- AMDパイルドライバー(2012年、FMA3およびFMA4)[ 16 ]
- インテル Haswell(2013年、FMA3のみ)[ 17 ]
- AMD Steamroller (2014、FMA3 および FMA4)
- AMD Excavator(2015、FMA3およびFMA4)
- Intel Skylake(2015、FMA3のみ)
- AMD Zen(2017、FMA3のみ)
- エルブルス-8SV(2018)
GPU および GPGPU ボード:
- AMD GPU(2009年以降)
- TeraScale 2「Evergreen」シリーズベース
- Graphics Core Nextベース
- Nvidia GPU(2010)以降
- Intel GPU:
- Sandy Bridge以降の統合GPU :
- インテルMIC(2012)
- ARM Mali T600 シリーズ(2012) 以上
- ベクトルプロセッサ:
2回以上の丸めを含むバリアント
[編集]MADの切り捨て
[編集]MADDのより単純な実装では、乗算結果を切り捨ててから加算します。これにより精度上の利点は得られず(実際、精度は低くなります)、2010年以前は、GPUでは正確なFMAよりもMADDの方が一般的にサポートされていました。例として、Nvidia PTXの「FMAD」命令が挙げられます。[ 18 ]
OpenCL最適化オプションは、OpenCL 1.0で「精度を下げて」等価な式を計算する関数を に-cl-mad-enable置き換えることを可能にします。 [ 19 ]このオプションと の精度は、OpenCLの新しいバージョンではより微妙になり、バージョン3.0以降では「埋め込みプロファイル」でのみ精度を下げられるようになりました。[ 20 ]a * b + cmad(a, b, c)mad()
追加の中間精度による丸め
[編集]DEC ( Digital Equipment Corporation ) VAXの命令は、ホーナーの規則を用いて、一連の乗算と加算のステップを用いてPOLY多項式を評価するために使用される。命令の説明では、乗算と加算が単一のFMAステップで実行されるかどうかは指定されていない。この命令は、1977年の11/780での最初の実装以来、VAX命令セットの一部となっている。 [ 21 ] Bob Supnikによると、マシンは内部的に拡張精度で乗算と加算を実行し、その後ターゲット形式に変換する。[ 22 ]そのため、乗算後に丸めステップが発生する。結果として、この演算はターゲット形式での単純な演算よりも精度が高いものの、IEEEのFMA定義を満たさない。a * b + c
この動作は、 x87FLT_EVAL_METHOD == 2で使用する場合と同等です。
参照
[編集]参考文献
[編集]- ^ 「ラドゲートの分析機械の実現可能性」。2019年8月7日時点のオリジナルよりアーカイブ。2020年8月30日閲覧。
- ^ Lyakhov, Pavel; Valueva, Maria; Valuev, Georgii; Nagornov, Nikolai (2020年1月). 「切り捨てられた乗算累算ユニットに基づくデジタルフィルタ性能向上手法」 .応用科学. 10 (24): 9052. doi : 10.3390/app10249052 .
- ^ Tung Thanh Hoang; Sjalander, M.; Larsson-Edefors, P. (2009年5月). 「FlexCoreプロセッサ拡張のためのダブルスループット積算ユニット」. 2009 IEEE International Symposium on Parallel & Distributed Processing . pp. 1– 7. doi : 10.1109/IPDPS.2009.5161212 . ISBN 978-1-4244-3751-1. S2CID 14535090 .
- ^ Kang, Jongsung; Kim, Taewhan (2020-03-01). 「PV-MAC: オンデバイス畳み込みニューラルネットワークにおける精度変動性を利用した乗算・累算ユニット構造」 . Integration . 71 : 76–85 . doi : 10.1016/j.vlsi.2019.11.003 . ISSN 0167-9260 . S2CID 211264132 .
- ^ "mad - ps" . 2019年11月20日. 2021年8月14日閲覧。
- ^ Whitehead, Nathan; Fit-Florea, Alex (2011). 「精度とパフォーマンス:NVIDIA GPUの浮動小数点演算とIEEE 754準拠」(PDF) . nvidia . 2013年8月31日閲覧。
- ^ "fmadd instrs" . IBM .
- ^ Kahan, William (1996-05-31). 「IEEE規格754 二進浮動小数点演算用」 .
- ^ Quinnell, Eric (2007年5月).浮動小数点融合積和アーキテクチャ(PDF) (博士論文) . 2011年3月28日閲覧。
- ^ Markstein, Peter (2004年11月). Goldschmidtアルゴリズムを用いたソフトウェアによる除算と平方根(PDF) . 第6回実数とコンピュータに関する会議. CiteSeerX 10.1.1.85.9648 .
- ^ 「バグ 20785 - Pragma STDC * (C99 FP) が実装されていない」 . gcc.gnu.org . 2022年2月2日閲覧。
- ^ 「最適化オプション(GNUコンパイラコレクション(GCC)の使用)」gcc.gnu.org . 2022年2月2日閲覧。
- ^ Montoye, RK; Hokenek, E.; Runyon, SL (1990年1月). 「IBM RISC System/6000浮動小数点演算ユニットの設計」. IBM Journal of Research and Development . 34 (1): 59– 70. doi : 10.1147/rd.341.0059 .

- ^ 「Godson-3 が x86 をエミュレート: 新しい MIPS 互換の中国製プロセッサには x86 翻訳用の拡張機能が搭載されている」。
- ^ 「STM32 Cortex-M33 MCUプログラミングマニュアル」(PDF) . ST . 2024年5月6日閲覧。
- ^ Hollingsworth, Brent (2012年10月). 「新しい「ブルドーザー」および「パイルドライバー」命令」 AMD Developer Central.
- ^ 「Intel、CPU設計ロードマップに22nmオクトコア「Haswell」を追加」 The Register . 2012年2月17日時点のオリジナルよりアーカイブ。 2008年8月19日閲覧。
- ^ Nvidia (2011年2月14日). 「OpenCLベストプラクティスガイド」(PDF) . developer.download.nvidia.com . 2025年9月27日閲覧。
- ^ 「OpenCL仕様バージョン: 1.0 ドキュメントリビジョン: 43」(PDF)。
- ^ 「OpenCL™仕様バージョン3.0.19(5.8.6.3.最適化オプション)」 . registry.khronos.org .
- ^ 「今週のVAX命令:POLY」 。2020年2月13日時点のオリジナルよりアーカイブ。
- ^ Bob Supnik. 「VAX が POLY を失った経緯」(PDF) .