乘積累加運算

乘積累加運算

乘積累加運算(英語:Multiply Accumulate, MAC)是在數位訊號處理器或一些微處理器中的特殊運算。實現此運算操作的硬體電路單元,被稱為“乘數累加器”。這種運算的操作,是將乘法的乘積結果和累加器 A 的值相加,再存入累加器。 若沒有使用 MAC 指令,上述的程式可能需要二個指令,但 MAC 指令可以使用一個指令完成。而許多運算(例如卷積運算、點積運算、矩陣運算、數字濾波器運算、乃至多項式的求值運算)都可以分解為數個 MAC 指令,因此可以提高上述運算的效率。

簡介

MAC指令的輸入及輸出的數據類型可以是整數、定點數或是浮點數。若處理浮點數時,會有兩次的數值修約(Rounding),這在很多典型的DSP上很常見。若一條MAC指令在處理浮點數時只有一次的數值修約,則這種指令稱為“融合乘加運算”/“積和熔加運算”(fused multiply-add, FMA)或“熔合乘法累積運算”(fused multiply–accumulate, FMAC)。

浮點運算中

當使用整數時,操作通常是精確的(以2的冪為單位計算)。 但是浮點數只有一定的數學精度。 也就是說,數字浮點運算通常不是關聯的或分散式的。 (請參閱浮點#精度問題。)因此,無論是使用兩個捨入執行乘法加法,還是使用單個捨入(融合乘法加法)進行一次運算,結果都會產生差異。 IEEE 754-2008規定必須進行一次捨入,才能得到更準確的結果。

積和熔加運算

融合乘加運算的操作和乘積累加的基本一樣,對於浮點數的操作也是一條指令完成。但不同的是,非融合乘加的乘積累加運算,處理浮點數時,會先完成b×c的乘積,將其結果數值修約到N個比特,然後才將修約後的結果與暫存器a的數值相加,再把結果修約到N個比特;融合乘加則是先完成a+b×c的操作,獲得最終的完整結果後方才修約到N個比特。由於減少了數值修約次數,這種操作可以提高運算結果的精度,以及提高運算效率和速率。

積和融加運算可以顯著提升像是這些運算的性能和精度:

•點積

•矩陣乘法

•多項式方程求解(像是秦九韶算法等)

•牛頓法求解函式的零點

積和融加運算通常被依靠用來獲取更精確的運算結果。然而,Kahan指出,如果不加思索地使用這種運算操作,在某些情況下可能會帶來問題。像是平方差公式 x− y,它等價於(( x× x) − y× y),若果x與y已知數值,使用積和融加運算來求結果,哪怕 x= y時,因為在進行首次乘法操作時無視低位的有效比特,可能會使運算結果出錯,如果是多步運算,第一步就出錯則會連累後續的運算結果接連出錯,比如前述的平方差求值後,再取結果的平方根,那么這個結果也會出錯。

點積指令

一些機器將多個融合乘法加法運算組合成單個步驟,例如, 在兩個128位SIMD暫存器上執行四元素點積a0×b0 + a1×b1 + a2×b2 + a3×b3,具有單周期吞吐量。

支持

FMA操作包含在IEEE 754-2008中。

DEC VAX的POLY指令用於使用一系列乘法和加法步驟來評估具有Horner規則的多項式。指令描述不指定是否使用單個fma步驟執行乘法和加法。[7]該指令自1977年原始的11/780實現以來一直是VAX指令集的一部分。

1999程式語言標準支持通過fma標準數學庫函式進行FMA操作,以及基於FMA控制最佳化的標準編譯指示。

融合的乘法-加法運算是在IBM POWER1(1990)處理器[8]中作為multiply-add融合引入的,但從那時起已被添加到眾多其他處理器中:

•HP PA-8000(1996)及以上版本

•英特爾安騰(2001)

•STI Cell(2006)

•富士通SPARC64 VI(2007)及以上

•(MIPS兼容)龍芯-2F(2008)

•Elbrus-8SV(2018)

帶有FMA3和/或FMA4指令集的x86處理器:

•AMD Bulldozer(2011年,僅限FMA4)

•AMD打樁機(2012,FMA3和FMA4)

•AMD Steamroller(2014)

•英特爾Haswell(2013年,僅限FMA3)

帶VFPv4和/或NEONv2的ARM處理器:

•ARM Cortex-M4F(2010)

•ARM Cortex-A5(2012)

•ARM Cortex-A7(2013)

•ARM Cortex-A15(2012)

•Qualcomm Krait(2012)

•Apple A6(2012)

•所有ARMv8處理器

GPU和GPGPU板:

•Advanced Micro Devices GPU(2009)及更新版本

•TeraScale 2“Evergreen”系列產品

•NVidia GPU(2010)及更新版本

•Maxwell-based(2014)

•Pascal(2016)

•Volta(2017)

•英特爾MIC(2012)

•ARM Mali T600系列(2012)及以上

套用到微處理器中的方法

一種微處理器中的方法,用以預備執行一±A*B±C形式的融合乘積62相加運算,其通過傳送第一與第二乘積62相加微指令至一或多個指令執行單元,以完成完整融合乘積62相加運算;第一乘積62相加微指令導引一未捨入非冗餘結果向量、自(a)A與B的部分乘積、或(b)具有A與B部分乘積的C中的一選項的一第一相加運算產生;如果第一相加運算並未包括C,則第二乘積62相加微指令導引具有未捨入非冗餘結果向量的C的一第二相加運算的執行,第二乘積62相加微指令亦導引、自未捨入非非冗餘結果向量產生最終捨入結果,其中,最終捨入結果為融合乘積62相加運算的一完全結果。

相關詞條

熱門詞條

聯絡我們