Daha düşük hassasiyetle optimize edin

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
ziyaret edin.

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 emin olun.

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örleştirme vektörleri alır. 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 söz konusu biçimi her ikisinde 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:

  1. 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.
  2. VK_KHR_shader_float16_int8 destekleniyorsa VkFizikselDeviceShaderKaydırma16Int8Features yapı işaretçisi bir VkPhysicalDeviceFeatures2.pNext zincire gider.
  3. shaderFloat16 ve shaderInt8 alanlarını kontrol edin Çağrıdan sonra VkPhysicalDeviceShaderFloat16Int8Features sonuç yapısı vkGetPhysicalDeviceFeatures2(). Alan değeri true ise biçim gölgelendirici programı aritmetiği için desteklenir.
ziyaret edin.

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
ziyaret edin.

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 gerekir.

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;