Bagikan melalui


Aturan floating-point (Direct3D 11)

Direct3D 11 mendukung beberapa representasi floating-point. Semua komputasi floating-point beroperasi di bawah subset yang ditentukan dari aturan floating-point presisi tunggal IEEE 754 32-bit.

Aturan floating-point 32-bit

Ada dua set aturan: yang sesuai dengan IEEE-754, dan yang menyimpang dari standar.

Aturan IEEE-754 yang terhormat

Beberapa aturan ini adalah satu opsi di mana IEEE-754 menawarkan pilihan.

  • Bagi dengan 0 menghasilkan +/- INF, kecuali 0/0 yang menghasilkan NaN.
  • log (+/-) 0 menghasilkan -INF. log nilai negatif (selain -0) menghasilkan NaN.
  • Akar kuadrat timbal balik (rsq) atau akar kuadrat (sqrt) dari angka negatif menghasilkan NaN. Pengecualiannya adalah -0; sqrt(-0) menghasilkan -0, dan rsq(-0) menghasilkan -INF.
  • INF - INF = NaN
  • (+/-) INF / (+/-)INF = NaN
  • (+/-) INF * 0 = NaN
  • NaN (OP apa pun) nilai apa pun = NaN
  • Perbandingan EQ, GT, GE, LT, dan LE, ketika salah satu atau kedua operan adalah NaN mengembalikan FALSE.
  • Perbandingan mengabaikan tanda 0 (sehingga +0 sama dengan -0).
  • NE perbandingan, ketika salah satu atau kedua operan adalah NaN mengembalikan TRUE.
  • Perbandingan nilai non-NaN terhadap +/- INF mengembalikan hasil yang benar.

Penyimpangan atau persyaratan tambahan dari aturan IEEE-754

  • IEEE-754 memerlukan operasi floating-point untuk menghasilkan hasil yang merupakan nilai terdekat yang dapat diwakili dengan hasil yang tak terbatas-tepat, yang dikenal sebagai round-to-nearest-even. Direct3D 11 mendefinisikan persyaratan yang sama: Operasi floating-point 32-bit menghasilkan hasil yang berada dalam 0,5 unit-last-place (ULP) dari hasil yang tak terbatas-tepat. Ini berarti bahwa, misalnya, perangkat keras diizinkan untuk memotong hasil menjadi 32-bit daripada melakukan round-to-nearest-even, karena itu akan mengakibatkan kesalahan paling banyak 0,5 ULP. Aturan ini hanya berlaku untuk penambahan, pengurangan, dan perkalian.

  • Tidak ada dukungan untuk pengecualian floating-point, bit status, atau perangkap.

  • Denorm dibersihkan ke nol yang dipertahankan tanda pada input dan output dari setiap operasi matematika floating-point. Pengecualian dibuat untuk setiap I/O atau operasi pergerakan data yang tidak memanipulasi data.

  • Status yang berisi nilai floating-point, seperti Viewport MinDepth/MaxDepth, nilai BorderColor, dapat disediakan sebagai nilai denorm dan mungkin atau mungkin tidak dibersihkan sebelum perangkat keras menggunakannya.

  • Operasi min atau maks memerah denorm untuk perbandingan, tetapi hasilnya mungkin atau mungkin tidak denorm memerah.

  • Input NaN ke operasi selalu menghasilkan NaN pada output. Tetapi pola bit yang tepat dari NaN tidak diperlukan untuk tetap sama (kecuali operasi adalah instruksi pemindahan mentah - yang tidak mengubah data.)

  • Operasi min atau maks yang hanya satu operan adalah NaN mengembalikan operand lainnya sebagai hasilnya (bertentangan dengan aturan perbandingan yang kita lihat sebelumnya). Ini adalah aturan IEEE 754R.

    Spesifikasi IEEE-754R untuk operasi floating point min dan max menyatakan bahwa jika salah satu input ke min atau maks adalah nilai QNaN yang tenang, hasil operasi adalah parameter lainnya. Contohnya:

    min(x,QNaN) == min(QNaN,x) == x (same for max)
    

    Revisi spesifikasi IEEE-754R mengadopsi perilaku yang berbeda untuk min dan maks ketika satu input adalah nilai SNaN "sinyal" versus nilai QNaN:

    min(x,SNaN) == min(SNaN,x) == QNaN (same for max)
    
    

    Umumnya, Direct3D mengikuti standar untuk aritmatika: IEEE-754 dan IEEE-754R. Tapi dalam hal ini, kami memiliki penyimpangan.

    Aturan aritmatika di Direct3D 10 dan yang lebih baru tidak membuat perbedaan antara nilai NaN yang tenang dan memberi sinyal (QNaN versus SNaN). Semua nilai NaN ditangani dengan cara yang sama. Dalam kasus min dan maks, perilaku Direct3D untuk nilai NaN apa pun seperti bagaimana QNaN ditangani dalam definisi IEEE-754R. (Untuk kelengkapan - jika kedua input adalah NaN, nilai NaN apa pun dikembalikan.)

  • Aturan IEEE 754R lainnya adalah min(-0,+0) == min(+0,-0) == -0, dan max(-0,+0) == max(+0,-0) == +0, yang menghormati tanda, berbeda dengan aturan perbandingan untuk nol yang ditandatangani (seperti yang kita lihat sebelumnya). Direct3D merekomendasikan perilaku IEEE 754R di sini, tetapi tidak memberlakukannya; hal ini diperbolehkan agar hasil membandingkan nol bergantung pada urutan parameter, menggunakan perbandingan yang mengabaikan tanda-tanda.

  • x*1,0f selalu menghasilkan x (kecuali denorm memerah).

  • x/1.0f selalu menghasilkan x (kecuali denorm memerah).

  • x +/- 0,0f selalu menghasilkan x (kecuali denorm yang dibersihkan). Tapi -0 + 0 = +0.

  • Operasi fused (seperti gila, dp3) menghasilkan hasil yang tidak kurang akurat daripada kemungkinan urutan serial terburuk evaluasi ekspansi operasi yang tidak difus. Definisi pengurutan terburuk yang mungkin, untuk tujuan toleransi, bukan definisi tetap untuk operasi yang menyatu tertentu; itu tergantung pada nilai input tertentu. Langkah-langkah individu dalam ekspansi yang tidak ditolak masing-masing diizinkan toleransi 1 ULP (atau untuk instruksi apa pun Direct3D memanggil dengan toleransi laks yang lebih dari 1 ULP, semakin banyak toleransi laks yang diizinkan).

  • Operasi fused mematuhi aturan NaN yang sama dengan operasi non-menyatu.

  • sqrt dan rcp memiliki toleransi ULP 1. Shader reciprocal dan reciprocal square-root instruksi, rcp dan rsq, memiliki sendiri persyaratan presisi santai terpisah.

  • Kalikan dan bagi setiap operasi pada tingkat presisi floating-point 32-bit (akurasi menjadi 0,5 ULP untuk dikalikan, 1,0 ULP untuk timbal balik). Jika x/y diimplementasikan secara langsung, hasilnya harus lebih besar atau sama akurasinya daripada metode dua langkah.

Aturan floating point 64-bit (presisi ganda)

Driver perangkat keras dan tampilan secara opsional mendukung floating-point presisi ganda. Untuk menunjukkan dukungan, saat Anda memanggil ID3D11Device::CheckFeatureSupport dengan D3D11_FEATURE_DOUBLES, driver mengatur DoublePrecisionFloatShaderOpsdari D3D11_FEATURE_DATA_DOUBLES ke TRUE. Driver dan perangkat keras kemudian harus mendukung semua instruksi floating-point presisi ganda.

Instruksi presisi ganda mengikuti persyaratan perilaku IEEE 754R.

Dukungan untuk pembuatan nilai denormalisasi diperlukan untuk data presisi ganda (tidak ada perilaku flush-to-zero). Demikian juga, instruksi tidak membaca data yang didenormalisasi sebagai nol yang ditandatangani, mereka menghormati nilai denorm.

Aturan floating-point 16-bit

Direct3D 11 juga mendukung representasi angka floating-point 16-bit.

Format:

  • 1 bit tanda dalam posisi bit MSB
  • 5 bit eksponen bias (e)
  • 10 bit pecahan (f), dengan bit tersembunyi tambahan

Nilai float16 (v) mengikuti aturan berikut:

  • jika e == 31 dan f != 0, maka v adalah NaN terlepas dari s
  • jika e == 31 dan f == 0, maka v = (-1)s*tak terbatas (tak terbatas yang ditandatangani)
  • jika e adalah antara 0 dan 31, maka v = (-1)s*2(e-15)*(1.f)
  • jika e == 0 dan f != 0, maka v = (-1)s*2(e-14)*(0.f) (angka denormalisasi)
  • jika e == 0 dan f == 0, maka v = (-1)s*0 (nol yang ditandatangani)

Aturan floating-point 32-bit juga berlaku untuk angka floating-point 16-bit, disesuaikan untuk tata letak bit yang dijelaskan sebelumnya. Pengecualian untuk ini meliputi:

  • Presisi: Operasi yang tidak ditolak pada angka floating-point 16-bit menghasilkan hasil yang merupakan nilai terdekat yang dapat direpresentasikan ke hasil yang tak terbatas-tepat (dibulatkan ke genap terdekat, per IEEE-754, diterapkan ke nilai 16-bit). Aturan floating-point 32-bit mematuhi toleransi 1 ULP, aturan floating-point 16-bit mematuhi 0,5 ULP untuk operasi yang tidak ditolak, dan ULP 0,6 untuk operasi yang menyatu.
  • Angka floating-point 16-bit mempertahankan denorm.

Aturan floating-point 11-bit dan 10-bit

Direct3D 11 juga mendukung format floating-point 11-bit dan 10-bit.

Format:

  • Tidak ada bit tanda
  • 5 bit eksponen bias (e)
  • 6 bit pecahan (f) untuk format 11-bit, 5 bit pecahan (f) untuk format 10-bit, dengan bit tersembunyi tambahan dalam kedua kasus.

Nilai float11/float10 (v) mengikuti aturan berikut:

  • jika e == 31 dan f != 0, maka v adalah NaN
  • jika e == 31 dan f == 0, maka v = +infinity
  • jika e adalah antara 0 dan 31, maka v = 2(e-15)*(1.f)
  • jika e == 0 dan f != 0, maka v = *2(e-14)*(0.f) (angka yang didenormalisasi)
  • jika e == 0 dan f == 0, maka v = 0 (nol)

Aturan floating-point 32-bit juga berlaku untuk angka floating-point 11-bit dan 10-bit, disesuaikan untuk tata letak bit yang dijelaskan sebelumnya. Pengecualian meliputi:

  • Presisi: Aturan floating-point 32-bit mematuhi 0,5 ULP.
  • Angka floating-point 10/11-bit mempertahankan denorm.
  • Operasi apa pun yang akan menghasilkan angka kurang dari nol dijepit menjadi nol.

Sumber

Tekstur