Frage

meine Bildverarbeitung Projekt arbeitet mit Graustufen-Bildern. Ich habe ARM Cortex-A8-Prozessor-Plattform. Ich mag die Verwendung des NEONS machen.

Ich habe ein Graustufenbild (man denke an das Beispiel unten) und in meinem alogorithm, ich habe nur die Spalten hinzuzufügen.

Wie kann ich laden vier 8-Bit-Pixelwerte in parallel, die sind uint8_t , vier uint32_t in einer der 128- Bit NEON Register? Was intrinsische mache ich das verwenden zu tun?

I Mittel:

alt text

Ich muss sie als 32 Bit geladen werden, weil wenn Sie genau hinschauen, den Moment, ich 255 + 255 512 ist, die nicht in einem 8-Bit-Register gehalten werden kann.

z.

255 255 255 255 ......... (640 pixels)
255 255 255 255
255 255 255 255
255 255 255 255
.
.
.
.
.
(480 pixels) 
War es hilfreich?

Lösung

Ich werde empfehlen, dass Sie ein wenig Zeit verbringen Verständnis, wie SIMD auf ARM arbeitet. Schauen Sie sich:

Werfen Sie einen Blick auf:

  1. http: //blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/
  2. http: //blogs.arm.com/software-enablement/196-coding-for-neon-part-2-dealing-with-leftovers/
  3. http: // blogs.arm.com/software-enablement/241-coding-for-neon-part-3-matrix-multiplication/
  4. http://blogs.arm.com/software-enablement/277-coding-for-neon-part-4-shifting-left-and-right/

Sie, um loszulegen. Anschließend können Sie Ihren SIMD-Code mit Inline-Assembler implementieren oder intrinsics entsprechende ARM von domen empfohlen.

Andere Tipps

Abhängig von Ihrem Compiler und (möglichen Mangel an) Erweiterungen.

Ie. für GCC, könnte dies ein Ausgangspunkt sein: http: //gcc.gnu .org / onlinedocs / gcc / ARM-NEON-Intrinsics.html

Wenn Sie zu 480 8-Bit-Werte summieren müssen dann würden Sie technisch benötigen 17 Bit Zwischenlagerung. wenn Sie die Ergänzungen in zwei Stufen, dh Top-240 Zeilen dann unteren 240 Zeilen jedoch durchführen, können Sie es in 16-Bit tun jeder. Dann können Sie die Ergebnisse aus den beiden Hälften hinzufügen, um die endgültige Antwort zu erhalten.

Es gibt tatsächlich eine NEON Anweisung, die geeignet ist für Ihren Algorithmus namens vaddw. Es wird ein dword-Vektor in einen Vektor qword, wobei die letzteren Elemente enthält, hinzuzufügen, die doppelt so breit ist wie die ersteren sind. In Ihrem Fall kann vaddw.u8 verwendet werden 8 Pixel Akkumulatoren 8 16-Bit hinzuzufügen. Dann vaddw.u16 verwendet werden kann, die zwei Sätze von acht 16-Bit-Akkumulatoren in einen Satz von 8 32-Bit diejenigen hinzufügen -. Beachten Sie, dass Sie den Befehl zweimal verwenden müssen, um beide Hälften zu erhalten

Bei Bedarf können Sie auch die Werte auf 16-Bit konvertieren zurück oder 8-Bit unter Verwendung vmovn oder vqmovn.

Es ist nicht Anweisung, die Ihren 4 8bit-Wert in 4 laden kann 32-Bit-Register.

Sie müssen sie laden und dann ein vshl zweimal verwenden. weil Neon 32 Register nicht auf 8 Pixel zu arbeiten haben können Sie (und nicht 4)

Sie können mit nur 16 Bit registrieren. es sollte genug sein, um ...

Laden den 4 Bytes eines einspurigen Ladebefehl unter Verwendung von (vld1 <register>[<lane>], [<address]) in ein Q-Register, dann mit zwei Move-langen Anweisungen (vmovl), um sie auf 16 und dann auf 32 Bits zuerst zu fördern. Das Ergebnis sollte so etwas wie (in GNU-Syntax)

sein
vld1 d0[0], [<address>] @Now d0 = (*<addr>, *<addr+1>, *<addr+2>, *<addr+3>, <junk>, ... <junk> )
vmovl.u8 q0, d0 @Now q1 = (d0, d1) = ((uint16_t)*<addr>, ... (uint16_t)*<addr+3>, <junk>, ... <junk>)
vmovl.u16 q0, d2 @Now d0 = ((uint32_t)*<addr>, ... (uint32_t)*<addr+3>), d1 = (<junk>, ... <junk>)

Wenn Sie diese <address> garantieren können, ist 4-Byte-ausgerichtet ist, dann schreibt [<address>: 32] statt in dem Ladebefehl, einen Zyklus oder zwei zu speichern. Wenn Sie das tun und die Adresse wird nicht ausgerichtet sind, werden Sie einen Fehler erhalten, aber.

Um, ich nur realisiert werden Sie wollen intrinsics verwenden, nicht Montage, also hier ist die gleiche Sache mit intrinsics.

uint32x4_t v8; // Will actually hold 4 uint8_t
v8 = vld1_lane_u32(ptr, v8, 0);
const uint16x4_t v16 = vget_low_u16(vmovl_u8(vreinterpret_u8_u32(v8)));
const uint32x4_t v32 = vmovl_u16(v16);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top