Die Befehle VLD (Vector Load) und VST (Vector Store) sind grundlegende Instruktionen für den Datenaustausch mit den NEON-Registern. Die spezifischen Varianten VLDM und VSTM stehen für “Vector Load Multiple” und “Vector Store Multiple” und werden verwendet, um mehrere Register gleichzeitig zu laden oder zu speichern.
Mit dem VLDM-Befehl lassen sich mehrere Datenblöcke gleichzeitig aus dem Speicher in verschiedene NEON-Register laden. Statt die Register einzeln zu befüllen, können mehrere Register in einem Schritt geladen werden. So lädt zum Beispiel VLDM R1, {D0-D3}
die NEON-Register D0 bis D3 mit Daten, die aus dem Speicherbereich stammen, dessen Startadresse im ARM-Register R1
angegeben ist.
Der VSTM-Befehl dient dazu, Daten aus mehreren NEON-Registern auf einmal in den Speicher zu schreiben. Statt die Inhalte einzelner Register nacheinander zu speichern, können mehrere Register auf einen Schlag gesichert werden. Beispielsweise speichert der Befehl VSTM R1, {D0-D3}
die Daten aus den Registern D0 bis D3 in den Speicherbereich, der durch die im Register R1
hinterlegte Adresse bestimmt wird.
Die NEON-Einheit ermöglicht es auch, Daten in einer spezifischen Anordnung zu laden und zu speichern.
Der VLD-Befehl lädt Daten direkt aus dem Speicher in die NEON-Register.
vldX.size {D0-Dn},[Rs]
X
legt das Interleave-Muster fest und definiert den Abstand der Elemente innerhalb der Struktur (1, 2, 3, 4).size
gibt die Größe der Daten an (8, 16, 32 oder 64 Bit).D0-Dn
spezifiziert die Register, in die die Daten geladen werden.[Rs]
stellt die Speicheradresse dar, von der die Daten abgerufen werden.Der VST-Befehl hingegen speichert die Daten aus den NEON-Registern wieder zurück in den Speicher. Nachdem die Daten in den Registern verarbeitet wurden, ermöglicht VST das Ablegen der Ergebnisse in einem bestimmten Speicherbereich.
vstX.size {D0-Dn},[Rd]
X
steht auch hier für das Interleave-Muster und bestimmt den Datenabstand (1, 2, 3, 4).size
spezifiziert die Größe der zu speichernden Daten (8, 16, 32 oder 64 Bit).D0-Dn
gibt die Register an, deren Inhalt gespeichert wird.[Rd]
bezeichnet die Speicheradresse, an die die Daten geschrieben werden.Interleaving
und De-Interleaving
bestimmen, wie Daten beim Laden und Speichern zwischen dem Speicher und den NEON-Registern angeordnet werden.
Beim Laden von Daten aus dem Speicher in NEON-Register können die Daten entflechtet (de-interleaved) werden. Das bedeutet, dass Daten, die im Speicher “verschachtelt” abgelegt sind, beim Laden auf mehrere Register verteilt und sauber getrennt werden. Diese Technik wird häufig genutzt, um komplexe Datensätze effizient zu verarbeiten.
Umgekehrt können beim Speichern von Daten aus den NEON-Registern die Inhalte verschachtelt (interleaved) abgelegt werden. Beim Speichern von Daten aus den NEON-Registern können die Daten verschachtelt (interleaved) werden. Hierbei werden die Registerdaten in einem verschachtelten Muster kombiniert und im Speicher gespeichert, wie es in manchen Multimedia-Anwendungen üblich ist.
Bei den Store-Befehlen (VST) hängt die Anzahl der benötigten Register ebenfalls von der Art des Interleaving ab:
In einem Assemblercode wird eine 128-Bit-Variable namens mydata
definiert:
mydata: .quad 0x0102030405060708, 0x090a0b0c0d0e0f10
Da ARM-Prozessoren normalerweise im Little-Endian-Format arbeiten, wird die Reihenfolge der Bytes im Speicher umgedreht. Das bedeutet, dass die Daten wie folgt im Speicher abgelegt werden:
0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01
(für das erste Quadword)0x10 0x0f 0x0e 0x0d 0x0c 0x0b 0x0a 0x09
(für das zweite Quadword)vld1.8 {d0}, [r0]
dann wird das Register d0
direkt mit den ersten 8 Bytes aus dem Speicher gefüllt. Das Register d0
enthält danach:
d0[7] | d0[6] | d0[5] | d0[4] | d0[3] | d0[2] | d0[1] | d0[0] |
---|---|---|---|---|---|---|---|
0x08 | 0x07 | 0x06 | 0x05 | 0x04 | 0x03 | 0x02 | 0x01 |
Das bedeutet, die Bytes werden in der Reihenfolge, wie sie im Speicher liegen, nacheinander in das Register geladen.
vld2.8 {d0, d1}, [r0]
dann passiert Folgendes:
0x08
) wird in d0[7]
geladen.0x07
) wird in d1[7]
geladen.0x06
) wird in d0[6]
geladen.0x05
) wird in d1[6]
geladen.Das Ergebnis sieht dann so aus:
Register d0
:
d0[7] | d0[6] | d0[5] | d0[4] | d0[3] | d0[2] | d0[1] | d0[0] |
---|---|---|---|---|---|---|---|
0x08 | 0x06 | 0x04 | 0x02 | 0x10 | 0x0e | 0x0c | 0x0a |
Register d1
:
d1[7] | d1[6] | d1[5] | d1[4] | d1[3] | d1[2] | d1[1] | d1[0] |
---|---|---|---|---|---|---|---|
0x07 | 0x05 | 0x03 | 0x01 | 0x0f | 0x0d | 0x0b | 0x09 |
Beim De-Interleaving werden die Daten nicht einfach nacheinander in ein einzelnes Register geladen. Stattdessen werden die Daten auf mehrere Register verteilt:
d0
, d1
, d2
).Im obigen Beispiel hat das De-Interleaving also zur Folge, dass die Daten von mydata
abwechselnd in d0
und d1
geladen werden. Das erste Byte geht in d0
, das zweite in d1
, das dritte wieder in d0
usw. So werden die Daten effektiv verteilt, was bei bestimmten Berechnungen oder Datenverarbeitungen nützlich sein kann.
Die Vektorregister D0
und D1
sind mit folgenden Werten initialisiert:
0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01
0x10 0x0f 0x0e 0x0d 0x0c 0x0b 0x0a 0x09
Wenn wir die Daten aus diesen Registern ohne Interleaving in den Speicher schreiben wollen, verwenden wir den folgenden Befehl:
vst1.8 {d0, d1}, [r0]
Dies speichert die Daten nacheinander im Speicher:
d0
im Speicher abgelegt.d1
.Im Speicher sehen die Daten dann so aus:
0x08 0x07 0x06 0x05 0x04 0x03 0x02 0x01
(Daten aus d0
)0x10 0x0f 0x0e 0x0d 0x0c 0x0b 0x0a 0x09
(Daten aus d1
)Beim Interleaving werden die Daten aus mehreren Registern abwechselnd in den Speicher geschrieben. Wenn wir die Daten aus den Registern d0
und d1
interleaved speichern möchten, verwenden wir:
vst2.8 {d0, d1}, [r0]
In diesem Fall passiert Folgendes:
d0[7]
wird in den Speicher geschrieben.d1[7]
geschrieben.d0[6]
und d1[6]
, und so weiter.Im Speicher sieht das Ergebnis dann so aus:
Position | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Wert | 08 | 10 | 07 | 0f | 06 | 0e | 05 | 0d | 04 | 0c | 03 | 0b | 02 | 0a | 01 | 09 |
Beim Interleaving werden die Daten nicht einfach nacheinander in den Speicher geschrieben. Stattdessen werden die Bytes aus mehreren Registern abwechselnd (interleaved) gespeichert:
d0
, d1
, d2
).zurück | Hauptmenü | weiter |