Moderne DSPs verfügen über leistungsstarke Datenadressrechenwerke, die im Stande sind, während eines Zyklus mehrere relative Adressen zu berechnen. In der Signalverarbeitung treten Daten zumeist nicht als einzelne Variable auf, sondern es müssen ganze Array-Puffer abgearbeitet werden. In einer typischen Applikation müssen ständig neue Daten in diesen Puffer übernommen und dafür die ältesten Werte verworfen werden. In C-Code würde dieses wie in aussehen (in diesem Beispiel ein FIR-Filter).
Wie man sieht, müssen am Ende alle Werte verschoben werden, was ineffizient ist. Die eleganteste Art, einen solchen Buffer zu implementieren, sind Ringspeicher (Circular-Puffer). Diese bestehen aus einem Anfangs- und einen Index-Zeiger und können bezüglich ihrer Länge spezifiziert werden. Wenn der Puffer voll ist, also die Länge überschritten wird, werden die ältesten Inhalte wieder überschrieben. Digitale Signalprozessoren unterstützen Ringspeicher auf der Hardware-Seite, indem sie die automatisierten Index-Zeiger zu Verfügung stellen. Diese Index-Zeiger können nicht nur für Ringpuffer genutzt werden, sondern auch, um Schleifen besonders effizient zu implementieren.
Schleifenabwickelung (Loop Unrolling)
Wie schon in Teil 1 im Abschnitt „Verhinderung von Pipeline Stalls“ erwähnt, führen Abhängigkeiten von Registern zu Pipeline-Stalls. Eine Methode, dies in einer Schleife zu verhindern, ist die Schleifenabwicklung (Loop Unrolling). Dazu benutzt man den ursprünglichen Schleifenkörper mehrmals in der Schleife und verhindert somit Abhängigkeiten, d.h., man führt mehrere Schleifenzyklen zu einer Schleife zusammen. Die Vermeidung der Pipeline-Stalls, welche durch Registerabhängigkeiten verursacht werden, kann die Ausführungszeiten erheblich verbessern. Außerdem kann diese Methode die Parallelisierung erleichtern. Die Iteration (Listing 2) würde abgewickelt wie in Listing 3 aussehen. Nachteile dieser Methode sind der höhere Bedarf an Registern und die erhebliche Erhöhung des Speicherbedarf des Programmcodes.