2016-06-19 6 views
2

J'essaie le code assembleur suivant:néon bras comparer les opérations génèrent un négatif

vclt.f32 q9,q0,#0 
vst1.i32 q9,[r2:128] 

Mais si la condition est vraie, l'élément correspondant Q9 est réglé sur un négatif au lieu de positif. Que puis-je faire pour en obtenir un positif?

+3

Il produit tous les 1 bits, ce qui est en effet -1 si vous l'interprétez comme le complément à 2 signé. Si vous n'avez besoin que d'un seul bit, que diriez-vous d'utiliser 'AND' bitwise. – Jester

+0

Donc c'est un résultat normal? Je pensais que c'était une sorte d'erreur. Merci – Andrey

+3

Oui, c'est normal. Ceci est plus utile pour les opérations de masquage, et vous pouvez facilement obtenir celui que vous voulez. – Jester

Répondre

1

Ceci est normal pour les instructions de comparaison de vecteurs, de sorte que vous pouvez utiliser le résultat de la comparaison sous forme de masque avec des instructions AND ou XOR ou d'autres cas d'utilisation.

Vous n'avez généralement pas besoin de +1. Si vous voulez compter le nombre d'éléments qui correspondent, par exemple, utilisez simplement une instruction de soustraction pour soustraire 0 ou -1 d'un accumulateur vectoriel. Pour obtenir un nombre entier +1, vous pouvez le soustraire de 0 ou le déplacer vers la droite par taille d'élément -1. (par exemple, décalage vers la droite logique de 31 pour laisser juste le bit bas 0 ou 1, et le reste des bits tout-zéro). Vous pourriez aussi ET avec un vecteur de + 1s que vous avez créé plus tôt.

Je ne sais pas lequel de ces derniers serait le mieux pour ARM, ou si cela dépend de la microarchitecture. (Je ne sais vraiment SIMD pour x86 SSE/AVX.) Je suis sûr que NEON peut faire au moins une des options que j'ai décrites, cependant.

+1

Il est incommode que les conditions en C/C++ renvoient '1' mais les conditions SIMD renvoient' -1'. J'ai fait une application où l'utilisateur pouvait sélectionner la taille du vecteur en temps réel (juste pour montrer la performance avec chacun). Par exemple.pour le flotteur, la taille pourrait être '1,4,8'. J'ai utilisé la VCL d'Agner. Mais j'ai dû créer des modèles spéciaux pour la taille du vecteur = 1 (c'est-à-dire les scalaires). Je suppose que le code scalaire et le code vectoriel doivent être différents pour comparer les performances de manière équitable. –

1

Il n'y a pas beaucoup de choses conditionnelles dans NEON, mais ce qu'il y a est vraiment seulement faisable avec la logique binaire, plutôt que booléenne, voir par exemple. vbsl.

Si vous avez des souvenirs horribles de BASIC et détestez vraiment les valeurs de vérité au niveau du bit, le moyen trivial de convertir le masque à une valeur booléenne est de prendre juste le bit haut de chaque élément:

vshr.u32 q9, q9, #31 

Bien que la négation, tout sans doute moins évident de lire un coup d'oeil, pourrait être mieux sage microscopiquement les performances dans certains cas:

vneg.s32 q9, q9 

(à partir d'une navigation par timings microarchitecture, les deux opérations sont à peu près identiques, mais certains avantages théoriques de vneg sur vshr sont qu'il consomme ses entrées plus tard Cortex-A8, et peut émettre sur les deux tuyaux ASIMD de Cortex-A57/A72)

Quoi qu'il en soit, comme dit en haut, cela ne fait vraiment sens pour stocker les résultat retour à la mémoire pour être regardé par le code non-vectorisé.

+0

Où les informations de microarchitecture sont-elles documentées? Y a-t-il quelque chose pour ARM comme [le guide de microarch de x86 d'Agner Fog et les timings d'instruction] (http://agner.org/optimize/), où les timings sont énumérés dans un format facile-à-renverser? Un google rapide trouvé [cette page ARM officielle] (http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0165b/I1028171.html), mais j'ai toujours trouvé les ARM site web officiel difficile à naviguer, esp. pour comparer quelque chose entre différentes versions d'ARM. (Naviguer dans le même arbre à partir d'une autre puce ARM de niveau supérieur est ridicule.) –

+1

@Peter Des cœurs plus anciens (jusqu'à Cortex-A9) donnent des temps de cycle général dans leurs TRM comme vous avez trouvé, les plus récents commencent à être publiés [guides d'optimisation] (http://infocenter.arm.com/help/topic/com.arm.doc.uan0016a/index.html); Malheureusement, il y a un peu d'écart au milieu. Le seul peu de rétro-ingénierie de style Agner que j'ai rencontré est [cette analyse partielle de Cortex-A7] (http://hardwarebug.org/2014/05/15/cortex-a7-instruction-cycle-timings/). – Notlikethat