2010-09-29 16 views
5

Ich bin nicht in der Lage, den Unterschied zwischen vld4_f32 und vld4q_f32 in ARM NEON Anweisungen zu erkennen.ARM NEON: Was ist der Unterschied zwischen vld4_f32 und vld4q_f32?

Die Verwirrung begann, als ich meine Codierlevel erhöhte und anfing, die Assembleranweisungen anstatt die weniger informativen intrinsics zu betrachten.

Der Grund, warum ich hier vld4 Variante Anweisung verwenden müssen, weil, ich möchte float32_t ‚s aus jeder 4. Position meiner großen Array erfassen.

alt text

Die vld4_f32 Spezifika und die entsprechenden Montageanleitung wie folgt aussehen (From this link)

float32x2x4_t vld4_f32 (const float32_t *) 
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0] 

Die vld4q_f32 Spezifika und die entsprechende Montageanleitung wie folgt aussieht

float32x4x4_t vld4q_f32 (const float32_t *) 
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0] 

Nun, auf der intrinsischen Ebene Der Unterschied, den ich sehe, ist der Rückgabetyp, aber wenn ich mir die Assembleranweisung und die Anzahl der Register anschaue, sehen beide ähnlich aus. Wie wird der Compiler oder der Assembler den Unterschied zwischen den beiden wissen?

Kann jemand mehr dazu klären und auch erklären, wie ich erreichen kann Laden 4 float32_t Werte, die bei jedem 4. Speicherplatz in eine einzigen positioniert sind, registrieren?

Antwort

7

Ja, ich habe den Unterschied herausgefunden. Ich habe CodeSourcery verwendet, um den tatsächlichen Registerinhalt für alle Ladeanweisungen zu sehen. Der Link, den ich gepostet habe, gibt nicht alle Details zum vld4q_f32.

Okay, zuerst die vld4_f32 kommt, lädt diese 4 d Registern (zB d16-19) jeweils d Register ist 64 Bits lang, so dass diese Anweisung werden die ersten 8 Werte verschachtelt mit einem Intervall von 4 laden, wie in der Abbildung unten gezeigt. alt text

Im zweiten Fall wird die vld4q_f32, lädt diese 8 d Register (z.B. d16-23) anstelle von vier. Für einen Leser dieser link ist es überhaupt nicht klar, dass 8 Register geladen werden. Als ich mir den zerlegten Code für eine vld4qf32 anschaute, verwendete er 8-d-Register.

Dieser Befehl wird in der Tat tun, was ich hoffte, es zu tun, d. H. 4 float32_t Werte zu laden, die im Intervall von 4 sind, wie in der folgenden Abbildung gezeigt. alt text

+1

Nun, vld4q Lasten 4 q Register, wie der Name schon sagt ... – jcayzac

1

ich zwei intrinsics zerlegt haben, vielleicht hilft es jemand:

// C++ 
uint32x4x4_t r = vld4q_u32((uint32_t *) output); 
// assembly 
VLD4.32   {D16,D18,D20,D22}, [R0]! 
VLD4.32   {D17,D19,D21,D23}, [R0] 

// C++ 
uint32x2x4_t r = vld4_u32((uint32_t *) output); 
// assembly 
VLD4.32   {D20-D23}, [R0]