11 votes

Comment réordonner les données vectorielles en utilisant les intrinsèques ARM Neon ?

Ceci est spécifiquement lié au codage SIMD ARM Neon. J'utilise les instrinsics ARM Neon pour certains modules d'un décodeur vidéo. J'ai des données vectorisées comme suit :

Il y a quatre éléments de 32 bits dans un registre Neon - disons, Q0 - qui est de taille 128 bits.

3B 3A 1B 1A

Il y a quatre autres éléments de 32 bits dans un autre registre Neon, par exemple Q1, qui a une taille de 128 bits.

3D 3C 1D 1C

Je veux que les données finales soient dans l'ordre comme indiqué ci-dessous :

1D 1C 1B 1A
3D 3C 3B 3A

Quels sont les instrinsics Neon qui permettent d'atteindre l'ordre de données souhaité ?

11voto

Nils Pipenbrinck Points 41006

Que diriez-vous de quelque chose comme ça :

  int32x4_t q0, q1;

  /* split into 64 bit vectors */
  int32x2_t q0_hi = vget_high_s32 (q0);
  int32x2_t q1_hi = vget_high_s32 (q1);
  int32x2_t q0_lo = vget_low_s32 (q0);
  int32x2_t q1_lo = vget_low_s32 (q1);

  /* recombine into 128 bit vectors */
  q0 = vcombine_s32 (q0_lo, q1_lo);
  q1 = vcombine_s32 (q0_hi, q1_hi);

En théorie, cela devrait se compiler en seulement deux instructions de déplacement car vget_high et vget_low réinterprètent simplement les registres Q de 128 bits en deux registres D de 64 bits. vcombine, quant à lui, se compile en un ou deux déplacements (selon l'allocation des registres).

Oh - et l'ordre des entiers dans la sortie pourrait être exactement à l'envers. Si c'est le cas, il suffit de permuter les arguments de vcombine_s32.

4voto

Pierre Lebeaupin Points 729

Rappelez-vous que chaque registre q est composé de deux registres d, par exemple la partie basse de q0 est d0 et la partie haute d1. Donc, en fait, cette opération ne fait que permuter d0 et d3 (ou d1 et d2, ce n'est pas tout à fait clair dans la présentation de vos données). Il existe même une instruction de permutation pour le faire en une seule instruction !

Avertissement : je ne connais pas les intrinsèques de Neon (je code directement en assembleur), mais je serais surpris que cela ne puisse pas être fait en utilisant des intrinsèques.

3voto

Paul R Points 104036

Il semblerait que vous puissiez utiliser la fonction VTRN instruction (par exemple vtrnq_u32 ) pour cela.

2voto

Pierre a raison.

vswp d0, d3

qui fera l'affaire.

@Pierre : J'ai lu l'article sur NEON sur votre blog il y a plusieurs mois. J'ai été agréablement surpris de voir qu'il y avait quelqu'un comme moi - écrivant des codes d'assemblage optimisés à la main, à la fois pour ARM et NEON. Je suis heureux de vous voir.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X