Comment déterminez-vous quelle «entrée n'a pas de sens»? Si c'est le résultat d'une comparaison, vous pouvez juste le bit ou votre résultat "normal" avec le masque de résultat de la comparaison.
C'est en fait un -NaN- le bit de signe est réglé. Envisagez un décalage à droite entier ( psrld xmm0,1) ou divisez par zéro / zéro ( xorps xmm0,xmm0/ divpd xmm0,xmm0) si cela n'est pas souhaitable.
Les fonctions mathématiques qui veulent renvoyer NaN veulent souvent également s'assurer que le bit d'exception rémanente non valide FP est défini dans MXCSR (ou déclenche réellement une exception si votre appelant a démasqué cette exception). Pour ce faire que , vous pouvez multiplier ou ajouter le NaN avec lui - même. par exemple
...
.error_return_path:
pcmpeqd xmm0, xmm0
mulsd xmm0, xmm0 ; Cause an FP-invalid operation.
ret
Ou mulsspour la simple précision float. mulpd/ mulpsserait également approprié.
Le modèle de bits pour la multiplication ou l'ajout de NaN avec NaN est certainement toujours un NaN, et devrait toujours être la même charge utile, donc toujours tout-en-un.
Le fait que la valeur de retour soit le résultat de mulsdou addsd(ou divsd) présente également l'avantage que si l'appelant utilise ce registre à plusieurs reprises dans une boucle, il n'aura pas de latence de contournement de domaine. (Sur la famille Sandybridge, cela dure éternellement. Par exemple, tout le monde addsd xmm1, xmm0aurait un cycle de latence supplémentaire de l'entrée xmm1 à la sortie xmm1 si xmm0 venait depcmpeqd , même si c'était il y a longtemps et que l'uop entier-SIMD a déjà pris sa retraite.)
Vous pourriez même le faire sans branchement si vous utilisez cmpsdou cmppd: vous pouvezorps transformer ce masque 0 / -1 en résultat pour le rendre NaN ou inchangé. Si un autre calcul définira (ou aura déjà) défini l'indicateur FP-invalide, ou si vous ne vous souciez pas de cela, vous êtes tous définis.
Méfiez-vous d'allonger le chemin critique avec cmp supplémentaire ou; si vous vous attendez à ce qu'il soit super rare, vous pouvez toujours comparer et créer des branches, par exemple avec movmskpd/ test eax,eax/ jnzsur un résultat cmppd pour voir si l'un ou l'autre bit a été défini => l'un des éléments SIMD a échoué une vérification.
Réponses:
Tout-en-un est un NaN silencieux (sans signalisation, alias normal), ce que vous voulez. La façon la plus simple d'en produire un est d'utiliser SSE2
pcmpeqd xmm0,xmm0
pour définir chaque bit du registre1
, c'est- à -dire l'entier complémentaire de 2-1
. ( Réglez tous les bits du registre CPU à 1 efficacement / Quelles sont les meilleures séquences d'instructions pour générer des constantes vectorielles à la volée? )C'est en fait un
-NaN
- le bit de signe est réglé. Envisagez un décalage à droite entier (psrld xmm0,1
) ou divisez par zéro / zéro (xorps xmm0,xmm0
/divpd xmm0,xmm0
) si cela n'est pas souhaitable.Les fonctions mathématiques qui veulent renvoyer NaN veulent souvent également s'assurer que le bit d'exception rémanente non valide FP est défini dans MXCSR (ou déclenche réellement une exception si votre appelant a démasqué cette exception). Pour ce faire que , vous pouvez multiplier ou ajouter le NaN avec lui - même. par exemple
Ou
mulss
pour la simple précisionfloat
.mulpd
/mulps
serait également approprié.Le modèle de bits pour la multiplication ou l'ajout de NaN avec NaN est certainement toujours un NaN, et devrait toujours être la même charge utile, donc toujours tout-en-un.
Le fait que la valeur de retour soit le résultat de
mulsd
ouaddsd
(oudivsd
) présente également l'avantage que si l'appelant utilise ce registre à plusieurs reprises dans une boucle, il n'aura pas de latence de contournement de domaine. (Sur la famille Sandybridge, cela dure éternellement. Par exemple, tout le mondeaddsd xmm1, xmm0
aurait un cycle de latence supplémentaire de l'entrée xmm1 à la sortie xmm1 si xmm0 venait depcmpeqd
, même si c'était il y a longtemps et que l'uop entier-SIMD a déjà pris sa retraite.)Vous pourriez même le faire sans branchement si vous utilisez
cmpsd
oucmppd
: vous pouvezorps
transformer ce masque 0 / -1 en résultat pour le rendre NaN ou inchangé. Si un autre calcul définira (ou aura déjà) défini l'indicateur FP-invalide, ou si vous ne vous souciez pas de cela, vous êtes tous définis.Méfiez-vous d'allonger le chemin critique avec cmp supplémentaire ou; si vous vous attendez à ce qu'il soit super rare, vous pouvez toujours comparer et créer des branches, par exemple avec
movmskpd
/test eax,eax
/jnz
sur un résultat cmppd pour voir si l'un ou l'autre bit a été défini => l'un des éléments SIMD a échoué une vérification.la source