# Multiply-Accumulate

Multiply-Accumulate (kurz: MAC) oder Multiply-Add (kurz: MAD) ist eine Rechenoperation, bei der zwei Faktoren multipliziert und das Produkt zu einem fortlaufenden Summanden (Akkumulator) addiert wird:
    $\ a\leftarrow a+(b\cdot c)$
Diese Operation wird intensiv bei der Verarbeitung digitaler Signale genutzt. Die Abkürzung MAC wird oft als Maßeinheit für die Leistungsfähigkeit solcher Systeme verwendet.
In FPGAs sowie ASICs wird diese Operation als Teil von DSP-Blöcken (Hardwareeinheiten) bereitgestellt; als Maschinenbefehl ist sie seit den 1980er Jahren in vielen Signalprozessoren wie auch seit Anfang der 2000er Jahre in konventionellen CPUs zu finden. Fused Multiply-Accumulate ist ein Multiply-Accumulate Befehl mit höherer Rechengenauigkeit.
Durch die Erweiterung des Hardware-Multiplizierers um den Akkumulator können Prozessoren die vollständige Operation oft genauso schnell wie eine klassische Multiplikation ausführen. Übliche Ausführungszeiten sind z. B. 2 Takte (40 ns) beim TMS320C40 von Texas Instruments mit 50 MHz Taktfrequenz und 5 Takte (2 ns) bei einem Intel Haswell mit 2,5 GHz Taktfrequenz. FPGAs können die Operation bis zu einigen 100 MHz in einem Taktzyklus ausführen.
Multiply-Accumulate-Befehle werden u. a. für digitale Filter und andere schnelle Berechnungen in der digitalen Bildverarbeitung, der Dekodierung von Videos und der Regelungstechnik eingesetzt. Die Akkumulation entspricht dabei der oft benötigten Integration, die Multiplikation berücksichtigt ein Differential oder bewirkt eine Gewichtung.
Die Argumente und das Ergebnis dieser Operation können je nach Prozessortyp und gewähltem Datentyp
* Integer-Zahlen (Motorola DSP56K),
* Festkomma-Zahlen (kein Typ bekannt),
* einfach genaue Gleitkomma-Zahlen (TI TMS320C30/40, Altivec, Intel Haswell) oder
* doppelt genaue Gleitkomma-Zahlen (Intel Haswell) sein
* 42 Bit Integer (FPGAs)

## Genauigkeit

Bei der MAC-Operation kann eine Verbesserung der Genauigkeit im finalen Ergebnis erzielt werden, indem die notwendige Rundung erst am Ende der MAC-Operation ausgeführt wird und die Zwischenergebnisse intern mit voller Auflösung ohne Rundungen durchgeführt werden. Diese Operation wird auch als englisch Fused Multiply Accumulate, abgekürzt FMA oder FMAC, bezeichnet. Die FMAC-Operation bedingt, im Gegensatz zur MAC-Operation, breitere Datenpfade und damit verbunden einen erhöhten Hardwareaufwand.

## Geschwindigkeit

Der Geschwindigkeitszuwachs kann bis zu 100 % betragen. So dauert in vielen DSPs der Multiply-Accumulate-Befehl genauso lange wie eine einzelne Addition oder eine einzelne Multiplikation (Beispiel: Texas Instruments TMS320C40). Der Geschwindigkeitszuwachs beim Intel Haswell ist geringer. Ein Multiply-Accumulate-Befehl dauert 5 Takte, eine einzelne Multiplikation 5 Takte und eine einzelne Addition 3 Takte, was zusammen 8 Takte ergibt und bei optimalem Einsatz ein Gewinn von 60 % bringt.
Auf der anderen Seite ist der Multiply-Accumulate-Befehl häufig der kritischste Befehl (kritischer Pfad) und begrenzt die Taktfrequenz nach oben. Ein weiteres Problem ist, dass man es in der Praxis sehr häufig mit Operationen zu tun hat, die die Form
    $\ z\leftarrow a+(b\cdot c)\cdot s$ mit $s=\pm 0{,}5,\,\,\pm 1,\,\,\pm 2$.
benötigen würden.
* Es wird häufig keine Addition, sondern eine Subtraktion des Produkts benötigt (Aufwand: Ein Exklusiv-Oder-Gatter für das Vorzeichen von $b$ oder $c$).
* Genauso häufig sind Skalierungen mit den Faktoren 0,5 oder 2 notwendig (Aufwand: Inkrement oder Dekrement für den Exponenten von $b$ oder $c$).
* Es wird eine 4-Operanden-Form benötigt, da $a$ nicht zerstört werden darf.
Im ersten Fall ist die MAC-Anweisung häufig nicht verwendbar, obwohl sie ein Exklusiv-Oder-Gatter von der benötigten Lösung entfernt ist. Im zweiten Fall bringt der MAC-Befehl einen deutlichen Nutzen, leider verbleibt eine Trivialoperation. Der dritte Fall wurde von AMD mit FMA4 adressiert, weiterhin lässt er sich durch Registerumbenennung heutiger CPUs meist verstecken.
Beispiele:
* Approximation des Kehrwertes von a mit dem Newton-Raphson-Verfahren: $x'=x\cdot ({\underline {2-a\cdot x}})$
* Approximation der reziproken Wurzel von a mit dem Newton-Raphson-Verfahren: $x'=x\cdot ({\underline {1{,}5-0{,}5\cdot a\cdot (x^{2})}})$
* Komplexwerte Multiplikation: $r={\underline {(r_{1}r_{2})-i_{1}i_{2}}},\,\,i=r_{1}i_{2}+r_{2}i_{1}$
* Iteration der Julia-Menge: $r_{n+1}=r_{n}^{2}{\underline {-i_{n}^{2}+r_{0}}},\,\,i_{n+1}={\underline {2r_{n}i_{n}+i_{0}}}$
* Approximation von Funktionen mittels Reihenentwicklung bis zum quadratischen Term