METAL SHADING LANGUAGE · BÖLÜM 8
Sayısal Uyumluluk
ASIL METİN Apple — Metal Shading Language Specification, Sürüm 4
Bu bölüm, Metal'in matematiksel işlemlerde doğruluk açısından kayan noktalı sayıları nasıl temsil ettiğini kapsar. Metal, IEEE 754 standardının bir alt kümesiyle uyumludur.
8.1 INF, NaN ve Denormal Sayılar
INF, tek duyarlıklı, yarı duyarlıklı ve brain kayan noktalı sayılar için desteklenmelidir.
NaN değerleri, tek duyarlıklı, yarı duyarlıklı ve brain kayan noktalı sayılar için desteklenmelidir (fast math devre dışıyken). Fast math etkinse, NaN veya INF (girdi ya da çıktı olarak) işleme davranışı tanımsızdır. Signaling NaN değerleri desteklenmez.
Aritmetik işlemlere girdi olarak verilen veya çıktı olarak üretilen denormal tek duyarlıklı, yarı duyarlıklı ya da brain kayan noktalı sayılar sıfıra yuvarlanabilir.
8.2 Yuvarlama Modu
Tek duyarlıklı, yarı duyarlıklı ve brain kayan noktalı işlemler için round ties to even veya round toward zero yuvarlama modlarından biri desteklenebilir.
8.3 Kayan Noktalı İstisnalar
Metal'de kayan noktalı istisnalar devre dışıdır.
8.4 ULP'ler ve Bağıl Hata
Tablo 8.1, tek duyarlıklı kayan noktalı temel aritmetik işlemlerinin ve matematik fonksiyonlarının ULP değerleri cinsinden verilen minimum doğruluğunu açıklar. Bir aritmetik işlemin ULP değerini hesaplamak için kullanılan referans değer, sonsuz hassasiyetteki sonuçtur.
Tablo 8.1. Tek Duyarlıklı Kayan Noktalı İşlemler ve Fonksiyonların Doğruluğu
| Matematik fonksiyonu | Minimum doğruluk |
|---|---|
| x + y | Doğru yuvarlanmış |
| x - y | Doğru yuvarlanmış |
| x * y | Doğru yuvarlanmış |
| acos | ≤ 4 ulp |
| acosh | ≤ 4 ulp |
| asin | ≤ 4 ulp |
| asinh | ≤ 4 ulp |
| atan | ≤ 5 ulp |
| atan2 | ≤ 6 ulp |
| atanh | ≤ 5 ulp |
| ceil | Doğru yuvarlanmış |
| copysign | 0 ulp |
| cos | ≤ 4 ulp |
| cosh | ≤ 4 ulp |
| cospi | ≤ 4 ulp |
| exp | ≤ 4 ulp |
| exp2 | ≤ 4 ulp |
| exp10 | ≤ 4 ulp |
| fabs | 0 ulp |
| fdim | Doğru yuvarlanmış |
| floor | Doğru yuvarlanmış |
| fma | Doğru yuvarlanmış |
| fmax | 0 ulp |
| fmin | 0 ulp |
| fmod | 0 ulp |
| fract | Doğru yuvarlanmış |
| frexp | 0 ulp |
| ldexp | Doğru yuvarlanmış |
| log10 | ≤ 4 ulp |
| modf | 0 ulp |
| nextafter | 0 ulp |
| pow | ≤ 16 ulp |
| powr | ≤ 16 ulp |
| rint | Doğru yuvarlanmış |
| round | Doğru yuvarlanmış |
| rsqrt | Doğru yuvarlanmış |
| sin | ≤ 4 ulp |
| sincos | ≤ 4 ulp |
| sinh | ≤ 4 ulp |
| sinpi | ≤ 4 ulp |
| sqrt | Doğru yuvarlanmış |
| tan | ≤ 6 ulp |
| tanpi | ≤ 6 ulp |
| tanh | ≤ 5 ulp |
| trunc | Doğru yuvarlanmış |
Tablo 8.2. Fast Math Etkinleştirildiğinde Tek Duyarlıklı İşlemler ve Fonksiyonların Doğruluğu
| Matematik fonksiyonu | Minimum doğruluk |
|---|---|
| x / y | y alanı 2⁻¹²⁶ ile 2¹²⁶ arasındayken ≤ 2.5 ulp |
| acos(x) | x alanı [-1, 1] içindeyken ≤ 5 ulp |
| acosh(x) | log(x + sqrt(x * x − 1.0)) olarak uygulanır |
| asin(x) | x alanı [-1, 1] ve |
| asinh(x) | log(x + sqrt(x * x + 1.0)) olarak uygulanır |
| atan(x) | ≤ 5 ulp |
| atan2(y, x) | atan(y/x) ve ±M.PI.F kullanılarak parçalı uygulama |
| cosh(x) | 0.5 * (exp(x) + exp(-x)) olarak uygulanır |
| exp(x) | ≤ 3 + floor(fabs(2 * x)) ulp |
| exp2(x) | ≤ 3 + floor(fabs(2 * x)) ulp |
| exp10(x) | exp2(x * log2(10)) olarak uygulanır |
| cos(x) | [-π, π] aralığında hata ≤ 2⁻¹³ |
| cospi(x) | [-1, 1] aralığında hata ≤ 2⁻¹³ |
| log10(x) | log2(x) * log10(2) olarak uygulanır |
| pow(x, y) | exp2(y * log2(x)) olarak uygulanır; x = 0 ve y = 0 için tanımsız |
| powr(x, y) | exp2(y * log2(x)) olarak uygulanır; x = 0 ve y = 0 için tanımsız |
| sinh(x) | 0.5 * (exp(x) − exp(-x)) olarak uygulanır |
| sincos(x) | sin(x) ve cos(x) için tanımlanan ULP değerleri |
| tan(x) | sin(x) * (1.0 / cos(x)) olarak uygulanır |
| rsqrt | ≤ 2 ulp |
| sqrt(x) | özel durumlar doğru şekilde ele alınarak x * rsqrt(x) olarak uygulanır |
ceil, copysign, fdim, floor, fma, fract, frexp, ilogb, ldexp, modf, rint, round ve trunc gibi ek fonksiyonlar belirtilen şekilde doğru yuvarlanmış veya 0 ulp doğruluğuna sahiptir.
8.5 Fast Math Davranışı
Her ne kadar bireysel matematik işlemlerinin ve fonksiyonlarının hassasiyeti Tablo 8.1–8.5'te belirtilmiş olsa da, fast math modundaki Metal derleyicisi (bkz. bölüm 1.6.5) kayan noktalı işlemlerin yeniden ilişkilendirilmesi gibi optimizasyonlar yapabilir. Bu optimizasyonlar sonuçları önemli ölçüde değiştirebilir.
Yeniden ilişkilendirme şu durumlara neden olabilir:
- Sıfırın işaretini değiştirmek veya yok saymak
- Argümanların ve sonuçların NaN veya ±INF olmadığını varsaymak
- Alt taşma veya üst taşma oluşturmak ya da engellemek
- Hassas yuvarlama davranışına dayanan kodları bozmak (örneğin
(x + 2^52) - 2^52)
ULP Tanımı
Eğer x, ardışık iki sonlu kayan noktalı sayı a ve b arasında yer alan bir gerçek sayıysa (ve bunlardan birine eşit değilse), o zaman:
ulp(x) = |b − a|
Aksi halde ulp(x), x'e en yakın olan ve birbirine eşit olmayan iki sonlu kayan noktalı sayı arasındaki mesafedir. Ek olarak:
ulp(NaN) = NaN
Bir sonuç yuvarlamadan önce subnormal ise sıfıra yuvarlanabilir. İşlenen değerler sıfıra yuvarlanırsa, sıfırın işareti tanımsızdır.
8.6 Kayan Nokta ve Tamsayı İçin Dönüştürme Kuralları
Bir kayan nokta türünden bir tamsayıya dönüştürme yapılırken round toward zero yuvarlama modu kullanılır.
Kayan nokta veya tamsayı türlerinden kayan nokta türlerine yapılan dönüştürmeler şu yuvarlama modlarını kullanabilir:
- round ties to even
- round toward zero
Ek kurallar:
- half ve bfloat türlerinden float türüne dönüşümler kayıpsızdır.
- float türünden half veya bfloat türüne dönüşümler mantisayı round ties to even kullanarak yuvarlar.
- float'tan half'a dönüştürme yapılırken oluşabilecek denormal sayılar sıfıra yuvarlanmayabilir.
- NaN bir tamsayıya dönüştürülürse sonuçtaki tamsayı 0 olur.
8.7 Doku Adresleme ve Dönüştürme Kuralları
Aşağıdaki fonksiyonlara verilen doku koordinatları INF veya NaN olamaz:
samplesample_comparegathergather_comparereadwrite
Davranış kuralları:
- Sınır dışı bir doku okuma işlemi, her bileşen için varsayılan değeri döndürür (bkz. bölüm 6.12).
- Metal, sınır dışı doku yazma işlemlerini yok sayar.
Bir multisample resolve işlemi yapılırken bu dönüştürme kuralları uygulanmaz.
8.7.1 Normalize Edilmiş Tamsayı Piksel Veri Türleri İçin Dönüştürme Kuralları
Bu bölüm, normalize edilmiş tamsayı piksel veri türleri ile kayan nokta değerleri arasındaki dönüşümü açıklar.
8‑, 10‑ veya 16‑bit normalize edilmiş işaretsiz tamsayı piksel değerlerine sahip dokular için sample ve read fonksiyonları değerleri aşağıdaki aralıktaki normalize edilmiş kayan nokta değerlerine dönüştürür:
[0.0 … 1.0]
8‑ veya 16‑bit normalize edilmiş işaretli tamsayı değerlerine sahip dokular için dönüşüm aşağıdaki aralıktaki normalize edilmiş kayan nokta değerlerini üretir:
[-1.0 … 1.0]
Bu dönüştürme kurallarının hassasiyeti, belirtilen köşe durumları dışında ≤ 1.5 ulp olacak şekilde garanti edilir.
Tablo 8.6. Normalize Edilmiş Bir Float Değerine Dönüştürme
| Kaynak tür | Dönüştürme kuralı | Köşe durumları |
|---|---|---|
| 1‑bit normalize edilmiş işaretsiz tamsayı | float(c) | 0 → 0.0, 1 → 1.0 |
| 2‑bit normalize edilmiş işaretsiz tamsayı | float(c) / 3.0 | 0 → 0.0, 3 → 1.0 |
| 4‑bit normalize edilmiş işaretsiz tamsayı | float(c) / 15.0 | 0 → 0.0, 15 → 1.0 |
| 5‑bit normalize edilmiş işaretsiz tamsayı | float(c) / 31.0 | 0 → 0.0, 31 → 1.0 |
| 6‑bit normalize edilmiş işaretsiz tamsayı | float(c) / 63.0 | 0 → 0.0, 63 → 1.0 |
| 8‑bit normalize edilmiş işaretsiz tamsayı | float(c) / 255.0 | 0 → 0.0, 255 → 1.0 |
| 10‑bit normalize edilmiş işaretsiz tamsayı | float(c) / 1023.0 | 0 → 0.0, 1023 → 1.0 |
| 16‑bit normalize edilmiş işaretsiz tamsayı | float(c) / 65535.0 | 0 → 0.0, 65535 → 1.0 |
| 8‑bit normalize edilmiş işaretli tamsayı | max(-1.0, float(c)/127.0) | -128 ve -127 → -1.0; 0 → 0.0; 127 → 1.0 |
| 16‑bit normalize edilmiş işaretli tamsayı | max(-1.0, float(c)/32767.0) | -32768 ve -32767 → -1.0; 0 → 0.0; 32767 → 1.0 |
Normalize edilmiş işaretsiz tamsayı biçimlerine sahip dokular için write fonksiyonları kayan nokta değerlerini tekrar 8‑ veya 16‑bit işaretsiz tamsayılara dönüştürür.
Normalize edilmiş işaretli tamsayı biçimlerine sahip dokular için write fonksiyonları kayan nokta değerlerini 8‑ veya 16‑bit işaretli tamsayılara dönüştürür.
Fast math'in dönüştürme işlemlerinin doğruluğunu değiştirmediğine dikkat edilmelidir.
NaN değerleri sıfıra dönüştürülür.
Kayan nokta değerlerinden normalize edilmiş tamsayı değerlere dönüşümler Tablo 8.7'de listelendiği şekilde gerçekleştirilir.
Tablo 8.7. Kayan Noktadan Normalize Edilmiş Tamsayı Değerine Dönüştürme
1‑bit normalize edilmiş işaretsiz tamsayı
x = min(max(f, 0.0), 1.0)
i0:0 = intRTNE(x)
2‑bit normalize edilmiş işaretsiz tamsayı
x = min(max(f * 3.0, 0.0), 3.0)
i1:0 = intRTNE(x)
4‑bit normalize edilmiş işaretsiz tamsayı
x = min(max(f * 15.0, 0.0), 15.0)
i3:0 = intRTNE(x)
5‑bit normalize edilmiş işaretsiz tamsayı
x = min(max(f * 31.0, 0.0), 31.0)
i4:0 = intRTNE(x)
6‑bit normalize edilmiş işaretsiz tamsayı
x = min(max(f * 63.0, 0.0), 63.0)
i5:0 = intRTNE(x)
8‑bit normalize edilmiş işaretsiz tamsayı
x = min(max(f * 255.0, 0.0), 255.0)
i7:0 = intRTNE(x)
10‑bit normalize edilmiş işaretsiz tamsayı
x = min(max(f * 1023.0, 0.0), 1023.0)
i9:0 = intRTNE(x)
Yarı duyarlıklı kayan noktalı piksel renk değerlerine sahip dokular için half'tan float'a dönüşümler kayıpsızdır. Float'tan half'a dönüşümler mantisayı round ties to even yuvarlama modunu kullanarak yuvarlar. Float'tan half'a dönüştürme sırasında oluşabilecek half veri türüne ait denormal sayılar sıfıra yuvarlanmayabilir. Bir float NaN değeri half türünde uygun bir NaN'e dönüştürülebilir veya sıfıra yuvarlanabilir. Bir float INF değeri half türünde uygun bir INF'e dönüştürülmelidir.
8.7.3 Tek Duyarlıklı Kayan Noktalı Piksel Veri Türü İçin Dönüştürme Kuralları
Tek duyarlıklı kayan noktalı piksel renk değerlerine sahip dokuların okunması ve yazılması için aşağıdaki kurallar geçerlidir:
- NaN değerleri bir NaN değerine dönüştürülebilir veya sıfıra yuvarlanabilir.
- INF değerleri korunmalıdır.
- Denormal sayılar sıfıra yuvarlanabilir.
- Diğer tüm değerler korunmalıdır.
8.7.4 10‑ ve 11‑bit Kayan Noktalı Piksel Veri Türü İçin Dönüştürme Kuralları
Bu kayan nokta biçimleri üs için 5 bit kullanır; 10‑bit kayan nokta türlerinde 5 bit mantisa, 11‑bit kayan nokta türlerinde 6 bit mantisa bulunur ve her iki tür için ek bir gizli bit vardır. İşaret biti yoktur. 10‑ ve 11‑bit kayan nokta türleri denormal değerleri korur.
- Üs ve mantisa 0 ise kayan nokta değeri 0.0 olur.
- Üs 31 ve mantisa != 0 ise sonuçtaki kayan nokta değeri NaN olur.
- Üs 31 ve mantisa 0 ise sonuçtaki kayan nokta değeri pozitif sonsuzluk olur.
- 0 <= exponent <= 31 ise kayan nokta değeri şöyledir:
2 ^ (exponent - 15) * (1 + mantissa / N)
- Üs 0 ve mantisa != 0 ise kayan nokta değeri bir denormal sayıdır:
2 ^ (exponent - 14) * (mantissa / N)
Mantisa 5 bit ise N = 32 olur. Mantisa 6 bit ise N = 64 olur.
10‑ veya 11‑bit kayan noktalı piksel veri türünden half veya tek duyarlıklı kayan nokta değerine dönüşüm kayıpsızdır. Half veya tek duyarlıklı kayan nokta değerinden 10‑ veya 11‑bit kayan nokta değerine dönüşüm ≤ 0.5 ULP olmalıdır. Bu kayan nokta türleri için sıfırdan küçük bir değerle sonuçlanan herhangi bir işlem sıfıra sınırlandırılır.
8.7.5 5‑bit Üslü 9‑bit Kayan Noktalı Piksel Veri Türü İçin Dönüştürme Kuralları
RGB9E5_SharedExponent ortak üs kullanan kayan nokta biçimi üs için 5 bit ve mantisa için 9 bit kullanır. İşaret biti yoktur.
Bu biçimden half veya tek duyarlıklı kayan nokta değerine dönüşüm kayıpsızdır ve her renk kanalı için şu şekilde hesaplanır:
2 ^ (shared exponent – 15) * (mantissa / 512)
Half veya tek duyarlıklı kayan noktalı RGB renk değerinden bu biçime dönüşüm aşağıdaki şekilde gerçekleştirilir. Burada:
- N, bileşen başına mantisa bit sayısıdır (9)
- B, üs bias değeridir (15)
- Emax, izin verilen maksimum biaslı üs değeridir (31)
Sınırlandırma
rc = max(0, min(sharedexpmax, r))
gc = max(0, min(sharedexpmax, g))
bc = max(0, min(sharedexpmax, b))
En büyük sınırlandırılmış bileşeni belirleme
maxc = max(rc, gc, bc)
Ön paylaşılmış üs hesaplama
expp = max(-B - 1, floor(log2(maxc)) + 1 + B)
İyileştirilmiş paylaşılmış üs hesaplama
maxs = floor((maxc / 2^(expp - B - N) + 0.5f))
exps = expp, if 0 <= maxs < 2^N
exps = expp + 1, if maxs = 2^N
Tamsayı mantisaları hesaplama
rs = floor(rc / 2^(exps - B - N) + 0.5f)
gs = floor(gc / 2^(exps - B - N) + 0.5f)
bs = floor(bc / 2^(exps - B - N) + 0.5f)
Burada:
sharedexpmax = ((2^N - 1) / 2^N) * 2^(Emax - B)
Half veya tek duyarlıklı kayan noktalı renk değerlerinden MTLPixelFormatRGB9E5Float ortak üs kayan nokta değerine dönüşüm ≤ 0.5 ULP doğruluğundadır.
8.7.6 İşaretli ve İşaretsiz Tamsayı Piksel Veri Türleri İçin Dönüştürme Kuralları
8‑ veya 16‑bit işaretli ya da işaretsiz tamsayı piksel değerlerine sahip dokular için doku örnekleme ve okuma fonksiyonları işaretli veya işaretsiz 32‑bit tamsayı piksel değeri döndürür. Bu bölümde açıklanan dönüşümlerin doğru şekilde doyurulmuş (saturated) olması gerekir.
Bu tamsayı dokularına yapılan yazma işlemleri Tablo 8.8'de listelenen dönüşümlerden birini gerçekleştirir.
Tablo 8.8. Tamsayı Piksel Veri Türleri Arasındaki Dönüşüm
32‑bit işaretli tamsayı → 8‑bit işaretli tamsayı
result = convert_char_saturate(val)
32‑bit işaretli tamsayı → 16‑bit işaretli tamsayı
result = convert_short_saturate(val)
32‑bit işaretsiz tamsayı → 8‑bit işaretsiz tamsayı
result = convert_uchar_saturate(val)
32‑bit işaretsiz tamsayı → 16‑bit işaretsiz tamsayı
result = convert_ushort_saturate(val)
Bir sRGB dokusundan örnekleme yapılırken sRGB uzayından doğrusal uzaya dönüşüm otomatik olarak gerçekleştirilir. sRGB'den doğrusal RGB'ye dönüşüm, sampler içinde belirtilen filtre uygulanmadan önce yapılır. Doku bir alpha kanalı içeriyorsa alpha verisi doğrusal renk uzayında saklanır.
Bir sRGB dokusuna yazılırken doğrusal uzaydan sRGB uzayına dönüşüm otomatik olarak yapılır. Doku bir alpha kanalı içeriyorsa alpha verisi doğrusal renk uzayında saklanır.
sRGB → Doğrusal RGB Dönüşümü
Normalize edilmiş 8‑bit işaretsiz tamsayı sRGB renk değeri bir kayan noktalı doğrusal RGB renk değerine (c) dönüştürülürken:
if (c <= 0.04045)
result = c / 12.92;
else
result = powr((c + 0.055) / 1.055, 2.4);
Yukarıdaki dönüşümün hassasiyeti, result değerinin tekrar normalleştirilmemiş bir sRGB değerine (8‑bit işaretsiz tamsayıya yuvarlama yapılmadan) dönüştürülmesiyle elde edilen sonsuz hassasiyetteki kayan noktalı değer ile orijinal sRGB 8‑bit işaretsiz tamsayı değeri arasındaki farkın ≤ 0.5 olmasını garanti etmelidir.
Doğrusal RGB → sRGB Dönüşümü
Bir doğrusal RGB kayan noktalı renk değeri (c) değerini normalize edilmiş 8‑bit işaretsiz tamsayı sRGB değerine dönüştürmek için:
if (isnan(c)) c = 0.0;
if (c > 1.0)
c = 1.0;
else if (c < 0.0)
c = 0.0;
else if (c < 0.0031308)
c = 12.92 * c;
else
c = 1.055 * powr(c, 1.0/2.4) - 0.055;
// Tamsayı ölçeğine dönüştür
c = c * 255.0;
// Tamsayıya dönüştür
c = c + 0.5;
// Ondalık kesir kısmını at
// Kalan kayan noktalı (tamsayı değerli) değeri bir tamsayıya dönüştür
Yukarıdaki dönüşümün hassasiyeti korunmalıdır.
BELİRTİMDE KOMŞULARI
BELİRTİMİN TAMAMI
- 1. Giriş2.921
- 2. Veri Türleri10.929
- 3. Operatörler1.638
- 4. Adres Alanları1.217
- 5. Fonksiyon ve Değişken Bildirimleri14.679
- 6. Metal Standart Kütüphanesi18.632
- 7. Metal Performans Primitifleri2.111
- 8. Sayısal Uyumluluk2.554
- 9. Ek273
BU SAYFA HAKKINDA
- Çeviri hatası bildire-posta