Comment Calculer le Vecteur Produit scalaire à l'Aide de l'ESS Intrinsèque des Fonctions en C
Je suis en train de multiplier deux vecteurs ensemble où chaque élément d'un vecteur est multiplié par l'élément dans le même index à l'autre vecteur. Je veux la somme de tous les éléments du vecteur résultant pour obtenir un numéro. Par exemple, le calcul devrait ressembler à ceci pour les vecteurs {1,2,3,4} et {5,6,7,8}:
1*5+2*6+3*7+4*8
Essentiellement, je suis prenant le produit scalaire de deux vecteurs. Je sais qu'il y est une ESS commande pour le faire, mais la commande n'a pas une fonction intrinsèque associée. À ce stade, je ne veux pas écrire assembly en ligne dans mon code en C, donc je veux utiliser uniquement les fonctions intrinsèques. Cela semble être une commune de calcul, donc je suis surpris par moi-même que je ne pouvais pas trouver la réponse sur Google.
Remarque: je suis d'optimisation pour une micro-architecture qui prend en charge jusqu'à SSE 4.2.
Merci pour votre aide.
OriginalL'auteur Sam | 2010-11-08
Vous devez vous connecter pour publier un commentaire.
Si vous êtes en train de faire un produit scalaire de plus les vecteurs, l'utilisation de multiplier et régulière
_mm_add_ps
(ou FMA) à l'intérieur de la boucle interne. Enregistrer la somme horizontale jusqu'à la fin.Mais si vous faites un produit scalaire de juste une paire de SIMD vecteurs:
GCC (au moins la version 4.3) comprend
<smmintrin.h>
avec SSE4.1 niveau intrinsèques, y compris le simple et double précision point des produits:Sur Intel intégrer des Processeurs (pas Atom/Silvermont) elles sont un peu plus rapide que de le faire manuellement avec de multiples instructions.
Mais sur AMD (y compris Ryzen),
dpps
est sensiblement plus lent. (Voir Agner le Brouillard de l'instruction tables)Comme un secours pour les processeurs plus anciens, vous pouvez utiliser cet algorithme pour créer le produit scalaire des vecteurs
a
etb
:et puis horizontal somme
r1
à l'aide de Moyen le plus rapide pour faire horizontale float somme vectorielle sur x86 (y voir une version commentée de cela, et pourquoi c'est plus rapide.)Une lente coûts alternatifs 2 shuffles par
hadd
, qui sera facilement goulot d'étranglement sur shuffle débit, en particulier sur les Processeurs Intel.cela dépend de votre matériel, il n'existe aucun cas qu'il est plus lent.
Je pense qu'il y a de meilleurs moyens pour horizontal somme que l'utilisation de
_mm_hadd_ps
. Voir stackoverflow.com/a/35270026/195787.OriginalL'auteur caf
Je dirais que le plus rapide de l'ESS de la méthode:
J'ai suivi - Moyen le plus rapide pour Faire Horizontale Float Somme Vectorielle Sur x86.
OriginalL'auteur Royi
J'ai écrit ce et compilé avec
gcc -O3 -S -ftree-vectorize -ftree-vectorizer-verbose=2 sse.c
Et GCC 4.3.0 auto-vectorisé:
Cependant, c'est seulement que si j'ai utilisé une boucle avec un nombre suffisant d'itérations, sinon la sortie détaillée permettrait de préciser que la vectorisation n'était pas rentable ou la boucle était trop petite. Sans le
__restrict__
mots-clés, il doit générer séparé, non-vectorisé versions pour traiter les cas où la sortieo
peut point sur l'une des entrées.Je collez les instructions comme un exemple, mais comme une partie de la vectorisation déroulé la boucle c'est pas très lisible.
OriginalL'auteur Ben Jackson
Il y a un article par Intel ici qui touche à point-implémentations de produit.
OriginalL'auteur DennyRolling