Grafik verilerinin ve gölgelendirici hesaplamalarının sayısal biçiminde Oyununuzun performansı üzerinde önemli bir etkiye sahip.
Optimum biçimler aşağıdakileri yapar:
- GPU önbellek kullanımının verimliliğini artırın
- Bellek bant genişliği tüketimini azaltın, güç tasarrufu yapın ve performansı artırın
- Gölgelendirici programlarında işlem hızını en üst düzeye çıkarma
- Oyununuzun CPU RAM kullanımını en aza indirin
Kayan nokta biçimleri
Modern 3D grafiklerdeki hesaplamaların ve verilerin çoğunda kayan nokta kullanılır numaraları'na dokunun. Android'de Vulkan, 32 veya 32 piksellik kayan nokta sayıları 16 bit boyutundadır. 32 bitlik bir kayan noktalı sayı genellikle tek kesinlik veya tam kesinlik; 16 bitlik bir kayan nokta sayı, yarım daha yüksek olması gerekir.
Vulkan, 64 bitlik bir kayan nokta türünü tanımlar, ancak bu tür yaygın olarak doğru değildir Vulkan cihazları tarafından desteklenir ve kullanılması önerilmez. 64 Bit kayan noktalı sayı genellikle çift duyarlıklı sayı olarak adlandırılır.
Tam sayı biçimleri
İşaretli ve işaretsiz tam sayı sayıları da veri ve hesaplamalar için kullanılır. İlgili içeriği oluşturmak için kullanılan standart tam sayı boyutu 32 bittir. Diğer bit boyutları için destek, cihaz şeklindedir bağımlıdır. Android çalıştıran Vulkan cihazlar genellikle 16 bit ve 8 biti destekler tam sayılar. Vulkan, 64 bitlik bir tam sayı türünü tanımlar ancak bu tür yaygın olarak doğru değildir. Vulkan cihazları tarafından desteklenir ve kullanılması önerilmez.
Yetersiz yarı hassasiyetli davranış
Modern GPU mimarileri, iki 16 bit değerini 32 bitlik bir çift ve çift üzerinde çalışan talimatları uygulayın. Optimum performans için skaler 16 bit kayan değişkenler kullanarak, verileri iki veya dört öğe şeklinde vektörlendirme yardımcı olabilir. Gölgelendirici derleyici, vektörde skaler değerler kullanabilir anlamına gelir. Ancak, skalerleri optimize etmek için derleyiciden yararlanıyorsanız emin olmak için derleyici çıkışını kontrol edin.
32 bit ve 16 bit hassasiyetli kayan noktaya dönüştürme işleminde işlem maliyetidir. Dinamik Arama Ağı Reklamları kampanyalarınızda hassas dönüşümleri en aza indirerek girin.
Uygulamanızın 16 bit ve 32 bit sürümleri arasındaki performans farklarını karşılaştırın kullanır. Yarı hassasiyet her zaman performans artışıyla sonuçlanmaz. özellikle de karmaşık hesaplamalar için kullanabilirsiniz. Çok kaynaklı algoritmalar Vektörleştirilmiş veriler üzerindeki çoklu ekleme (FMA) talimatlarının yarı hassasiyetle iyileştirilmiş performans.
Sayısal biçim desteği
Android'deki tüm Vulkan cihazlar tek duyarlıklı, 32 bit kayan noktayı destekler sayılar ve 32 bitlik tam sayı sayıları ile gölgelendirici hesaplamalarında kullanılır. Destek diğer biçimlerin sunulacağı ve kullanılabilir olduğu garanti edilmez uygun hale getiriyoruz.
Vulkan'da isteğe bağlı sayısal biçimler için iki destek kategorisi vardır: aritmetik ve depolama alanı. Belirli bir biçimi kullanmadan önce cihazın her iki biçimde de desteklediğinden emin olun tıklayın.
Aritmetik desteği
Bir Vulkan cihazının sayısal bir biçimin aritmetik desteğini bildirmesi için bu cihazın Gölgelendirici programlarında kullanılabilir. Android'deki Vulkan cihazlar genellikle şu aritmetik biçimleri vardır:
- 32 bit tam sayı (zorunlu)
- 32 bit kayan nokta (zorunlu)
- 8 bit tam sayı (isteğe bağlı)
- 16 bit tam sayı (isteğe bağlı)
- 16 bit yarı duyarlı kayan nokta (isteğe bağlı)
Bir Vulkan cihazının aritmetik olarak 16 bitlik tam sayıları destekleyip desteklemediğini belirlemek için
cihazın özelliklerini çağırarak
vkGetPhysicalDeviceFeatures2() işlevini kullanarak ve kontrol ederek
VkFizikselDeviceFeatures2 öğesindeki shaderInt16
alanı
doğru olduğundan emin olun.
Bir Vulkan cihazının 16 bit kayan öğeleri mi yoksa 8 bit tam sayıları mı desteklediğini belirlemek için şu adımları uygulayın:
- Cihazın VK_KHR_shader_float16_int8 Vulkan uzantısı. Uzantı 16 bit kayan nokta ve 8 bit tam sayı desteği için gereklidir.
VK_KHR_shader_float16_int8
destekleniyorsa VkFizikselDeviceShaderKaydırma16Int8Features yapı işaretçisi birVkPhysicalDeviceFeatures2.pNext
zincire gider.shaderFloat16
veshaderInt8
alanlarını kontrol edin Çağrıdan sonraVkPhysicalDeviceShaderFloat16Int8Features
sonuç yapısıvkGetPhysicalDeviceFeatures2()
. Alan değeritrue
ise biçim gölgelendirici programı aritmetiği için desteklenir.
Vulkan 1.1 veya 2022 sürümünde zorunlu değildir.
Android Baseline profili, VK_KHR_shader_float16_int8
desteği
uzantısı Android cihazlarda çok yaygındır.
Depolama alanı desteği
Bir Vulkan cihazı, depolama alanına sahip olmanız gerekir. VK_KHR_16bit_storage uzantısı 16 bit tam sayı ve 16 bit kayan nokta biçimlerini desteklediğini beyan eder. Dört depolama alanı türleri uzantı tarafından tanımlanır. Cihaz, 16 bit numaraları destekleyebilir depolama alanı türlerini kullanmanıza olanak tanımaz.
Depolama alanı türleri şunlardır:
- Depolama arabellek nesneleri
- Tek tip arabellek nesneleri
- İtme sabit blokları
- Gölgelendirici giriş ve çıkış arayüzleri
Android'deki Vulkan 1.1 cihazlarının tümü olmasa da çoğu depolama arabellek nesneleridir. GPU modeline bağlı olarak destek sağlanacağını varsaymayın. Cihazlar eski sürücülere sahip olması, depolama arabellek nesnelerini desteklemeyebilir, daha yeni sürücülere sahip cihazlarda kullanabilirsiniz.
Tek tip arabellekler, itme sabit blokları ve gölgelendiricide 16 bit biçimler için destek Giriş/çıkış arayüzleri genellikle GPU üreticisine bağlıdır. Şu tarihte: Android'de GPU'lar genellikle bu türlerin üçünü de destekler veya hiçbirini desteklemez oluşturabilirsiniz.
Vulkan aritmetiği ve depolama biçimi desteğini test eden örnek bir işlev:
struct ReducedPrecisionSupportInfo {
// Arithmetic support
bool has_8_bit_int_ = false;
bool has_16_bit_int_ = false;
bool has_16_bit_float_ = false;
// Storage support
bool has_16_bit_SSBO_ = false;
bool has_16_bit_UBO_ = false;
bool has_16_bit_push_ = false;
bool has_16_bit_input_output_ = false;
// Use 16-bit floats if we have arithmetic
// support and at least SSBO storage support.
bool use_16bit_floats_ = false;
};
void CheckFormatSupport(VkPhysicalDevice physical_device,
ReducedPrecisionSupportInfo &info) {
// Retrieve the device extension list so we
// can check for our desired extensions.
uint32_t device_extension_count;
vkEnumerateDeviceExtensionProperties(physical_device, nullptr,
&device_extension_count, nullptr);
std::vector<VkExtensionProperties> device_extensions(device_extension_count);
vkEnumerateDeviceExtensionProperties(physical_device, nullptr,
&device_extension_count, device_extensions.data());
bool has_16_8_extension = HasDeviceExtension("VK_KHR_shader_float16_int8",
device_extensions);
// Initialize the device features structure and
// chain the storage features structure and 8/16-bit
// support structure if applicable.
VkPhysicalDeviceFeatures2 device_features;
memset(&device_features, 0, sizeof(device_features));
device_features.sType = VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FEATURES_2;
VkPhysicalDeviceShaderFloat16Int8Features f16_int8_features;
memset(&f16_int8_features, 0, sizeof(f16_int8_features));
f16_int8_features.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_FLOAT16_INT8_FEATURES_KHR;
VkPhysicalDevice16BitStorageFeatures storage_features;
memset(&storage_features, 0, sizeof(storage_features));
storage_features.sType =
VK_STRUCTURE_TYPE_PHYSICAL_DEVICE_16BIT_STORAGE_FEATURES;
device_features.pNext = &storage_features;
if (has_16_8_extension) {
storage_features.pNext = &f16_int8_features;
}
vkGetPhysicalDeviceFeatures2(physical_device, &device_features);
// Parse the storage features and determine
// what kinds of 16-bit storage access are available.
if (storage_features.storageBuffer16BitAccess ||
storage_features.uniformAndStorageBuffer16BitAccess) {
info.has_16_bit_SSBO_ = true;
}
info.has_16_bit_UBO_ = storage_features.uniformAndStorageBuffer16BitAccess;
info.has_16_bit_push_ = storage_features.storagePushConstant16;
info.has_16_bit_input_output_ = storage_features.storageInputOutput16;
info.has_16_bit_int_ = device_features.features.shaderInt16;
if (has_16_8_extension) {
info.has_16_bit_float_ = f16_int8_features.shaderFloat16;
info.has_8_bit_int_ = f16_int8_features.shaderInt8;
}
// Get arithmetic and at least some form of storage
// support before enabling 16-bit float usage.
if (info.has_16_bit_float_ && info.has_16_bit_SSBO_) {
info.use_16bit_floats_ = true;
}
}
Veriler için hassasiyet düzeyi
Yarı duyarlıklı bir kayan nokta sayı, daha küçük bir değer aralığını temsil edebilir. tek duyarlıklı kayan nokta sayısından daha düşük doğruluktadır. Yarı hassasiyet, çoğu zaman basit ve kayıpsız bir tek duyarlıklılık. Ancak yarı kesinlik tüm kullanım durumlarında pratik olmayabilir. Bazı veri türlerinde, aralığın ve hassasiyetin azaltılması sansürsüz görüntülere neden olabilir olabilir.
Yarı kesinlikte temsil edilmeye iyi aday olan veri türleri kayan nokta şunları içerir:
- Verileri yerel alan koordinatlarında konumlandırma
- Sınırlı UV sarmalama ile daha küçük dokular için doku UV'leri -1,0 ila 1,0 koordinat aralığıyla sınırlandırılmıştır
- Normal, teğet ve bitangent veriler
- Köşe rengi verileri
- 0,0 odaklı düşük hassasiyetli gerekli veriler
Yarı duyarlı kayanda gösterilmesi önerilmez veri türleri şunlardır:
- Verileri küresel dünya koordinatlarına göre konumlandırma
- Bir atlas sayfası
Gölgelendirici kodunda doğruluk
OpenGL Gölgelendirme Dili (GLSL) ve Üst düzey Gölgelendirici Dili (HLSL) gölgelendirici esnek programlama dili desteği kesinlik veya açık hassasiyet. Esnek hassasiyet uygulanır kullanabilirsiniz. Açık hassasiyet, gerekliliği anlamına gelir. Android'deki Vulkan cihazlar genellikle Yüksek hassasiyetle önerildiğinde 16 bit biçimler Diğer Vulkan cihazları özellikle de desteklenmeyen grafik donanımı kullanan masaüstü bilgisayarlarda gibi, sabit hassasiyeti yoksayabilir ve 32 bit biçimlerini kullanmaya devam edebilir.
GLSL'deki depolama uzantıları
16 bit veya 16 bit desteğini etkinleştirmek için uygun GLSL uzantıları tanımlanmalıdır. Depolama ve tek tip arabellek yapılarında 8 bitlik sayısal biçimler. İlgili uzantı beyanları şunlardır:
// Enable 16-bit formats in storage and uniform buffers.
#extension GL_EXT_shader_16bit_storage : require
// Enable 8-bit formats in storage and uniform buffers.
#extension GL_EXT_shader_8bit_storage : require
Bu uzantılar GLSL'ye özeldir ve HLSL'de eşdeğerleri yoktur.
GLSL'de rahat hassasiyet
Öneride bulunmak için kayan nokta türünden önce highp
niteleyicisini kullanın.
yarı hassasiyetli kayan noktalı bir için tek duyarlıklı kayan nokta ve mediump
niteleyici.
Vulkan için GLSL derleyicileri, eski lowp
niteleyiciyi mediump
olarak yorumlar.
Esnek hassasiyetle ilgili bazı örnekler:
mediump vec4 my_vector; // Suggest 16-bit half precision
highp mat4 my_matrix; // Suggest 32-bit single precision
GLSL'de açık hassasiyet
GL_EXT_shader_explicit_arithmetic_types_float16
uzantısını
16 bit kayan nokta türlerinin kullanımını etkinleştirmek için GLSL kodu:
#extension GL_EXT_shader_explicit_arithmetic_types_float16 : require
GLSL'de 16 bitlik kayan nokta skaler, vektör ve matris türlerini tanımlamak için şu anahtar kelimeler:
float16_t f16vec2 f16vec3 f16vec4
f16mat2 f16mat3 f16mat4
f16mat2x2 f16mat2x3 f16mat2x4
f16mat3x2 f16mat3x3 f16mat3x4
f16mat4x2 f16mat4x3 f16mat4x4
Aşağıdakileri kullanarak GLSL'de 16 bit tam sayı skaler ve vektör türlerini bildirme anahtar kelimeler:
int16_t i16vec2 i16vec3 i16vec4
uint16_t u16vec2 u16vec3 u16vec4
HLSL'de rahat hassasiyet
HLSL, esnek hassasiyet yerine minimum hassasiyet terimini kullanır. Minimal
hassasiyet türü anahtar kelimesi minimum kesinliği belirtir, ancak derleyici
için daha yüksek kesinlik daha iyi bir seçimse, daha yüksek bir hassasiyet
hedef donanım. Minimum hassasiyetli 16 bitlik kayma,
min16float
anahtar kelime. Minimum hassasiyetli, imzalı ve imzasız 16 bitlik tam sayılar
sırasıyla min16int
ve min16uint
anahtar kelimeleri tarafından belirtilmektedir. Ek bilgiler
Minimum hassasiyet bildirimlerine örnek olarak aşağıdakiler verilebilir:
// Four element vector and four-by-four matrix types
min16float4 my_vector4;
min16float4x4 my_matrix4x4;
HLSL'de açık hassasiyet
Yarı hassasiyetli kayan nokta, half
veya float16_t
tarafından belirtilir
anahtar kelimeler. İmzalı ve imzasız 16 bit tam sayılar, int16_t
ve uint16_t
anahtar kelime içeriyor. Açık hassasiyetle ilgili diğer örnekler
beyanlar aşağıdakileri içerir:
// Four element vector and four-by-four matrix types
half4 my_vector4;
half4x4 my_matrix4x4;