Conversion d’indices basés sur la source en indices basés sur la destination

J’utilise les instructions AVX2 dans du code C.

L’instruction VPERMD prend deux vecteurs de 8 entiers a et idx et en génère un troisième, dst , en permutant a basant sur idx . Cela semble équivalent à dst[i] = a[idx[i]] for i in 0..7 . J’appelle cette source, car le mouvement est indexé en fonction de la source.

Cependant, j’ai mes indices calculés sous forme de destination. Ceci est naturel pour définir un tableau, et équivaut à dst[idx[i]] = a[i] for i in 0..7 .

Comment puis-je convertir un formulaire source en un formulaire cible? Un exemple de test est:

 {2 1 0 5 3 4 6 7} source-based form. {2 1 0 4 5 3 6 7} destination-based equivalent 

Pour cette conversion, je rest dans les registres ymm, ce qui signifie que les solutions basées sur la destination ne fonctionnent pas. Même si je devais les insérer séparément, car il ne fonctionne que sur des index constants, vous ne pouvez pas les définir.

Je suppose que vous dites implicitement que vous ne pouvez pas modifier votre code pour calculer des index basés sur la source en premier lieu? Je ne vois rien de ce que vous pouvez faire avec x86 SIMD, à part les instructions de dispersion AVX512 qui prennent des index basés sur dst.

Stocker en mémoire, inverser et recharger un vecteur peut en fait être la meilleure solution. (Ou transférer directement dans des registres de nombres entiers, et non par la mémoire, peut-être après un vextracti128 / packusdw, de sorte que vous n’avez besoin que de deux transferts de 64 bits d’un vecteur à un autre: movq et pextrq).

Quoi qu’il en soit, utilisez-les comme indices pour stocker un compteur dans un tableau en mémoire et rechargez-le en tant que vecteur. Ceci est toujours lent et moche, et inclut un retard d’échec de transfert de magasin. Par conséquent, cela vaut probablement la peine de modifier votre code générateur d’index pour générer des vecteurs de réorganisation aléatoire.