Dla funkcji, którą piszę, chciałbym zwrócić Nan, jeśli dane wejściowe nie mają sensu.
Jak w najprostszy sposób mogę wstawić NaN do rejestru xmm ?
Dla funkcji, którą piszę, chciałbym zwrócić Nan, jeśli dane wejściowe nie mają sensu.
Jak w najprostszy sposób mogę wstawić NaN do rejestru xmm ?
Odpowiedzi:
Wszyscy to cichy (bez sygnalizacji, aka normalny) NaN, który jest tym, czego chcesz. Najłatwiejszym sposobem na wyprodukowanie takiego jest SSE2, pcmpeqd xmm0,xmm0
aby ustawić każdy bit w rejestrze na 1
, tj. Liczbę całkowitą dopełniającą 2 -1
. ( Ustaw efektywnie wszystkie bity rejestru procesora na 1 / Jakie są najlepsze sekwencje instrukcji do generowania stałych wektorowych w locie? )
W rzeczywistości jest to -NaN
- bit znaku jest ustawiony. Rozważ liczbę całkowitą w prawo shift ( psrld xmm0,1
) lub podziel przez zero / zero ( xorps xmm0,xmm0
/ divpd xmm0,xmm0
), jeśli jest to niepożądane.
Funkcje matematyczne, które chcą zwrócić NaN, często chcą również upewnić się, że bit wyjątku lepkiego FP-nieprawidłowy zostanie ustawiony w MXCSR (lub faktycznie zgłosi wyjątek, jeśli osoba dzwoniąca zdemaskowała ten wyjątek). Aby to zrobić , że można mnożyć lub dodać NaN ze sobą. na przykład
...
.error_return_path:
pcmpeqd xmm0, xmm0
mulsd xmm0, xmm0 ; Cause an FP-invalid operation.
ret
Lub mulss
dla pojedynczej precyzji float
. mulpd
/ mulps
byłoby również odpowiednie.
Wzorzec bitowy dla zwielokrotnienia lub dodania NaN z NaN jest zdecydowanie nadal NaN i powinien nadal mieć ten sam ładunek, więc nadal wszystkie.
Posiadanie wartości zwracanej w wyniku mulsd
lub addsd
(lub divsd
) ma również tę zaletę, że jeśli osoba wywołująca używa tego rejestru wielokrotnie w pętli, nie będzie mieć opóźnienia w obejściu domeny. (W przypadku rodziny Sandybridge trwa to wiecznie. Np. Każdy addsd xmm1, xmm0
miałby dodatkowy cykl opóźnienia od wejścia xmm1 do wyjścia xmm1, gdyby xmm0 pochodziło pcmpeqd
, nawet jeśli to było dawno temu, a uop liczby całkowitej-SIMD już wycofał się.)
Możesz nawet być w stanie zrobić to bez rozgałęzień, jeśli użyjesz cmpsd
lub cmppd
: możesz orps
zamaskować maskę 0 / -1 w wyniku, aby ustawić NaN lub bez zmian. Jeśli jakieś inne obliczenia ustawią (lub już ustawią) flagę nieważności FP, lub jeśli nie przejmujesz się tym, wszystko jest ustawione.
Uważaj na wydłużenie ścieżki krytycznej o dodatkowe cmp / lub; jeśli spodziewasz się, że jest to bardzo rzadkie, możesz raczej porównać i rozgałęzić, np. z movmskpd
/ test eax,eax
/ jnz
na wyniku cmppd, aby sprawdzić, czy któryś bit został ustawiony => jeden z elementów SIMD nie sprawdził się.