Design: Dokumentasikan mengapa bit NaN tidak sepenuhnya deterministik

Dibuat pada 22 Mar 2016  ·  15Komentar  ·  Sumber: WebAssembly/design

(Saat ini saya tidak menganjurkan; ini jadi kami membuat keputusan yang tepat dan mengumpulkan materi untuk alasan.)

Melihat Nondeterminism.md , bagian bit NaN menonjol. Tentu saja utas dapat berpacu, sumber daya dapat habis, dan fitur dapat ditambahkan; itu adalah konsekuensi dari desain keseluruhan. Tapi bit NaN? Bisakah VM sedikit lebih pintar dan menangani ini? Ada dua masalah:

Ketika sebuah operasi mendapatkan lebih dari satu operan NaN, yang mana yang disebarkannya?

IEEE 754 membiarkan ini tidak ditentukan, tetapi setidaknya x86, ARM, dan Power semuanya memilih operan "pertama", dan itu adalah pilihan yang masuk akal.

Namun, memperbaiki pilihan pada tingkat wasm akan berarti bahwa implementasi wasm tidak dapat mengubah dan mengalikan floating-point, yang terkadang merupakan pengoptimalan yang berguna pada pra-VEX x86 di mana instruksi mengacaukan salah satu inputnya. Juga, itu akan membutuhkan siapa pun yang menggunakan VM berbasis LLVM untuk mengajarkannya bahwa menambah dan mengalikan tidak komutatif pada wasm.

Orang dapat berargumen bahwa ini bukan penghenti pertunjukan, jadi masalah ini secara teoritis dapat diperbaiki jika ada keinginan yang kuat.

Ketika sebuah operasi menghasilkan NaN dan tidak memiliki operan NaN, apa bit tandanya?

x86 menggunakan 1, ARM menggunakan 0.

Cara paling sederhana untuk memperbaikinya adalah dengan mengkanonikalisasi setelah setiap operasi floating-point. Ini bisa dilakukan, meskipun rumitnya adalah bahwa 0 dan 1 adalah nilai valid yang mungkin ketika ada operan NaN untuk disebarkan, jadi tidak cukup hanya memeriksa hasil NaN dan mengkanonikalisasi; seseorang harus memeriksa hasil NaN dan kekurangan operan NaN, dan baru kemudian melakukan kanonikalisasi.

Kanonikalisasi setelah _setiap_ operasi akan sangat mahal; pilihan lain adalah dengan hanya mengkanonikalisasi pada titik-titik komputasi yang "melarikan diri" (jalur kanonikalisasi pada dasarnya harus memutar ulang seluruh aliran komputasi untuk menentukan output NaN yang benar). Ini adalah peningkatan, tetapi kemungkinan masih menambah jumlah overhead yang signifikan.

Implementasi lain yang mungkin adalah membuka kedok pengecualian yang tidak valid, mengambil jebakan setiap kali NaN dihasilkan, dan kemudian melakukan kanonikalisasi dan kembali. Kelemahannya termasuk menggunakan mode CPU non-default, dan menjadi sangat lambat jika ada banyak invalid yang dihasilkan.

Sayangnya, pendekatan ini membawa kerugian yang signifikan. Kecuali ide-ide lain muncul, atau ada keinginan yang sangat kuat, ini tampaknya sulit untuk diperbaiki.


Satu hal lagi yang perlu diperhatikan adalah bahwa bit NaN sulit untuk diamati secara tidak sengaja, jadi ini bukan masalah portabilitas utama secara umum.

Apakah ada orang lain yang punya pemikiran untuk menambahkan?

clarification floating point

Komentar yang paling membantu

Saya ingin mengukur efek kinerja ini sebelum membuat keputusan. Saya pikir rantai alat kami masih terlalu matang untuk membuat pengukuran kinerja yang baik saat ini (ada tiang yang lebih panjang di jalan yang satu ini). Dengan kata lain: Saya ingin menghindari "kematian dengan seribu luka".

Semua 15 komentar

Satu hal lagi yang perlu diperhatikan adalah bahwa bit NaN sulit untuk diamati secara tidak sengaja

Apakah ada cara untuk membuat mereka tidak mungkin untuk mengamati atau setidaknya sedikit tanda?

IMO nondeterminisme NaN harus dibiarkan sendiri, mengingat sangat jarang perangkat lunak yang peduli dengan mereka. Apa kasus mengorbankan kinerja untuk membuat mereka deterministik?

Berikut adalah daftar cara seseorang dapat mengamati bit NaN:

  • reinterpret konversi
  • store ke memori linier dan memuat bit dengan interpretasi yang berbeda (atau membiarkan bit diamati secara eksternal)
  • meneruskan argumen ke call dari fungsi yang diimpor, atau mengembalikan nilai dari fungsi yang diekspor
  • copysign tanda sedikit ke non-NaN

VM dapat menyisipkan kode kanonikalisasi sebelum masing-masing kode tersebut; itulah ide "kanonikalisasi di titik pelarian" yang dibahas di atas. store sangat umum di jalur panas, jadi ini mungkin masih cukup mahal.

@qwertie Saya sangat peduli dengan mereka dan saya memiliki usecase yang bertumpu pada mereka yang deterministik. Tetapi seperti yang dibahas di sini, ada cara untuk membuatnya sepenuhnya deterministik meskipun tidak masuk dalam spesifikasi.

@qwertie Manfaat mungkin termasuk portabilitas yang sedikit lebih besar (misalnya, ada kode di dunia yang secara tidak bijaksana menggunakan fungsi totalOrder IEEE 754), reproduktifitas yang sedikit lebih besar, dan invarian yang lebih kuat saat melakukan perhitungan simetris di beberapa node.

store sangat umum di jalur panas, jadi ini mungkin masih cukup mahal.

Untuk kasus ini, bisakah kita selalu menentukan nilai tanda? jadi seperti buat saja 1 jika ditempatkan di mem?

@wanderer Pada dasarnya itulah yang diperlukan kanonikalisasi: periksa untuk melihat apakah nilainya adalah NaN, dan jika demikian, terapkan beberapa koreksi. Ini biasanya merupakan perbandingan ekstra dan bercabang di jalur panas.

Saya juga harus menambahkan, saya belum membandingkan salah satu opsi yang disebutkan dalam masalah ini; pembandingan apa pun yang dapat ditambahkan siapa pun di sini akan diterima.

Saya akan sangat condong ke tingkat non-determinisme saat ini, yang mendukung kinerja.
Saya sebenarnya agak terkejut bahwa wasm secara ketat mendefinisikan bit mantissa NaN.
Meskipun ini mungkin cukup untuk prosesor hari ini, siapa yang tahu prosesor masa depan apa yang akan datang.

Jika wasm dihasilkan dari bahasa tingkat tinggi, penerjemah itu dapat memberikan opsi untuk mengontrol tingkat semantik FP, mirip dengan -ffast-math misalnya. Penerjemah kemudian dapat menyisipkan perbaikan wasm tambahan yang diperlukan untuk memaksa nan ke format yang diinginkan. Untuk itu kami dapat menyediakan operator isNan atau normalizeNan, meskipun saya tidak menganjurkan untuk ini sekarang.

Singkatnya, "memperbaiki" ini sebaiknya diserahkan ke alat tingkat yang lebih tinggi, IMO.

+1 @mbodart. Sunting : oh lihat sebenarnya ada hal +1 sekarang :). Btw, saya pribadi berpikir Wasm = dominasi dunia dan oleh karena itu prosesor masa depan tidak akan menentangnya.

Saya ingin mengukur efek kinerja ini sebelum membuat keputusan. Saya pikir rantai alat kami masih terlalu matang untuk membuat pengukuran kinerja yang baik saat ini (ada tiang yang lebih panjang di jalan yang satu ini). Dengan kata lain: Saya ingin menghindari "kematian dengan seribu luka".

Saya setuju dengan @jfbastien. Efek kinerja perlu diukur terlebih dahulu sebelum mengutak-atik semantik.

Untuk lebih jelasnya, saat ini saya tidak menganjurkan perubahan di sini; Aku sedang mengumpulkan bahan rasional. Nondeterminisme bit NaN menonjol, dan menginginkan penjelasan. Dan sejauh yang saya ketahui, tidak ada yang mengukur efek kinerja dari membuat bit ini juga nondeterministik.

ARMv8 tidak selalu menyebarkan operan pertama ketika kedua operan adalah NaN. Aturannya adalah:

  • Jika satu operan adalah NaN yang tenang dan yang lainnya adalah NaN pensinyalan, sebarkan NaN pensinyalan.
  • Jika tidak, sebarkan operan pertama.

Saat saya membaca spesifikasi, ini berlaku untuk mode Aarch32 dan Aarch64 ARMv8.

Perilaku ini berbeda dari SSE yang menyebarkan operan pertama dalam kedua kasus.

Kedua arsitektur akan mengonversi sNaN menjadi qNaN dengan mengatur bit tenang sebelum menyebarkannya.

@stoklund Tempat yang bagus! Saya melewatkan ARM yang memilih NaN pertama tidak terjadi dalam kasus di mana NaN kedua memberi sinyal. Itu akan memperumit strategi yang saya susun untuk beberapa kasus NaN di atas, jadi kami dapat menyebutkannya dalam alasan.

Saya sekarang telah membuat #973 untuk mengusulkan teks spesifik yang merangkum hal di atas.

Apakah halaman ini membantu?
0 / 5 - 0 peringkat

Masalah terkait

konsoletyper picture konsoletyper  ·  6Komentar

chicoxyzzy picture chicoxyzzy  ·  5Komentar

cretz picture cretz  ·  5Komentar

artem-v-shamsutdinov picture artem-v-shamsutdinov  ·  6Komentar

void4 picture void4  ·  5Komentar