Bagaimana Anda bisa memasukkan NaN ke dalam register xmm?

9

Untuk fungsi yang saya tulis, saya ingin mengembalikan Nan jika inputnya tidak masuk akal.

Bagaimana saya bisa memasukkan NaN ke dalam register xmm dengan cara termudah?

Markus
sumber
1
Bagaimana Anda menentukan "input yang tidak masuk akal"? Jika ini adalah hasil perbandingan, Anda hanya bisa bitwise-atau hasil "normal" Anda dengan topeng hasil perbandingan.
chtz

Jawaban:

13

All-ones adalah NaN yang tenang (non-pensinyalan, alias normal), yang Anda inginkan. Cara termudah untuk menghasilkan satu adalah dengan SSE2 pcmpeqd xmm0,xmm0untuk mengatur setiap bit dalam register 1, yaitu integer komplemen 2's -1. ( Atur semua bit dalam register CPU ke 1 secara efisien / Apa urutan instruksi terbaik untuk menghasilkan konstanta vektor dengan cepat? )

Ini sebenarnya -NaN- bit tanda diatur. Pertimbangkan bilangan bulat kanan bilangan bulat ( psrld xmm0,1) atau bagi dengan nol / nol ( xorps xmm0,xmm0/ divpd xmm0,xmm0) jika itu tidak diinginkan.


Fungsi matematika yang ingin mengembalikan NaN sering juga ingin memastikan bit exception lengket FP-tidak valid diatur dalam MXCSR (atau benar-benar meningkatkan pengecualian jika pemanggil Anda membuka kedok pengecualian itu). Untuk melakukan itu , Anda bisa mengalikan atau menambahkan NaN dengan dirinya sendiri. misalnya

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

Atau mulssuntuk presisi tunggal float. mulpdSaya mulpsjuga akan pantas.

Pola bit untuk melipatgandakan atau menambah NaN dengan NaN jelas masih merupakan NaN, dan masih harus payload yang sama, jadi masih semuanya.

Memiliki nilai kembali sebagai hasil dari mulsdatau addsd(atau divsd) juga memiliki keuntungan bahwa jika pemanggil menggunakan register itu berulang kali dalam satu lingkaran, itu tidak akan memiliki latensi bypass lintas domain. (Pada keluarga Sandybridge, ini berlangsung selamanya. Misalnya setiap orang addsd xmm1, xmm0akan memiliki siklus latensi tambahan dari input xmm1 ke output xmm1 jika xmm0 berasal pcmpeqd, bahkan jika itu sudah lama sekali dan uop integer-SIMD sudah pensiun.)


Anda bahkan dapat melakukannya tanpa cabang jika Anda menggunakan cmpsdatau cmppd: Anda dapat orpsmenyamarkan 0 / -1 menjadi hasil untuk menjadikannya NaN atau tidak berubah. Jika beberapa perhitungan lain akan (atau akan sudah) menetapkan tanda tidak sah FP, atau jika Anda tidak peduli tentang itu, Anda sudah siap.

Waspadai perpanjangan jalur kritis dengan cmp ekstra / atau; jika Anda mengharapkannya sangat langka, Anda mungkin masih bisa membandingkan dan bercabang, misalnya dengan movmskpd/ test eax,eax/ jnzpada hasil cmppd untuk melihat apakah bit disetel => salah satu elemen SIMD gagal dalam beberapa pemeriksaan.

Peter Cordes
sumber