Wie kann man ein NaN in ein xmm-Register einfügen?


9

Für die Funktion, die ich schreibe, möchte ich eine Nan zurückgeben, wenn die Eingabe keinen Sinn ergibt.

Wie kann ich am einfachsten ein NaN in ein xmm-Register einfügen ?


1
Wie bestimmen Sie, welche "Eingabe keinen Sinn ergibt"? Wenn dies das Ergebnis eines Vergleichs ist, können Sie nur bitweise - oder Ihr "normales" Ergebnis mit der Ergebnismaske des Vergleichs.
21.

Antworten:


13

All-one ist ein leises (nicht signalisierendes, auch normales) NaN, was Sie wollen. Der einfachste Weg, eine zu erzeugen, besteht darin, mit SSE2 pcmpeqd xmm0,xmm0jedes Bit im Register auf 1die Komplement-Ganzzahl von 2 zu setzen -1. ( Setzen Sie alle Bits im CPU-Register effizient auf 1 / Was sind die besten Befehlssequenzen, um Vektorkonstanten im laufenden Betrieb zu generieren? )

Es ist eigentlich ein -NaN- das Vorzeichenbit ist gesetzt. Betrachten Sie eine ganzzahlige Rechtsverschiebung ( psrld xmm0,1) oder dividieren Sie durch Null / Null ( xorps xmm0,xmm0/ divpd xmm0,xmm0), wenn dies unerwünscht ist.


Mathematikfunktionen, die NaN zurückgeben möchten, möchten häufig auch sicherstellen, dass das FP-ungültige Sticky-Exception-Bit in MXCSR gesetzt wird (oder tatsächlich eine Ausnahme auslösen, wenn Ihr Anrufer diese Ausnahme entlarvt hat). Zu tun , dass , können Sie multiplizieren oder den NaN mit sich selbst hinzufügen. z.B

    ...
.error_return_path:
    pcmpeqd   xmm0, xmm0
    mulsd     xmm0, xmm0       ; Cause an FP-invalid operation.
    ret

Oder mulssfür einfache Präzision float. mulpdIch mulpswäre auch angemessen.

Das Bitmuster für das Multiplizieren oder Addieren von NaN mit NaN ist definitiv immer noch ein NaN und sollte immer noch die gleiche Nutzlast sein, also immer noch alle.

Wenn der Rückgabewert ein Ergebnis von mulsdoder addsd(oder divsd) ist, hat dies auch den Vorteil, dass der Anrufer, wenn er dieses Register wiederholt in einer Schleife verwendet, keine Bypass-Latenz beim Überqueren von Domänen aufweist. (In der Sandybridge-Familie dauert dies ewig. ZB addsd xmm1, xmm0würde jeder einen zusätzlichen Latenzzyklus von xmm1-Eingang zu xmm1-Ausgang haben, wenn xmm0 von kommt pcmpeqd, selbst wenn das schon lange her ist und das Integer-SIMD-UOP bereits in den Ruhestand gegangen ist.)


Möglicherweise können Sie dies sogar verzweigungslos tun, wenn Sie cmpsdoder verwenden cmppd: Sie können orpsdiese 0 / -1-Maske in ein Ergebnis umwandeln, um es NaN oder unverändert zu machen. Wenn eine andere Berechnung das FP-ungültige Flag setzt (oder bereits gesetzt hat) oder wenn Sie sich nicht darum kümmern, sind Sie fertig.

Achten Sie darauf, den kritischen Pfad nicht mit zusätzlichen cmp / oder zu verlängern. Wenn Sie erwarten, dass es sehr selten ist, können Sie lieber noch vergleichen und verzweigen, z. B. mit movmskpd/ test eax,eax/ jnzauf einem cmppd-Ergebnis, um festzustellen, ob eines der Bits gesetzt wurde => eines der SIMD-Elemente hat eine Prüfung nicht bestanden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.