Bellek havuzları

Bu sayfada, sürücü ile çerçeve arasında işlenen arabelleklerin verimli bir şekilde iletişimini sağlamak için kullanılan veri yapıları ve yöntemleri açıklanmaktadır.

Model derleme zamanında çerçeve sürücüye sabit işlenenlerin değerlerini sağlar. Sabit işlenenin ömrüne bağlı olarak değerleri ya bir HIDL vektöründe ya da paylaşılan bellek havuzunda bulunur.

  • Ömür boyu CONSTANT_COPY ise değerler model yapısının operandValues ​​alanında bulunur. HIDL vektöründeki değerler işlemler arası iletişim (IPC) sırasında kopyalandığından, bu genellikle yalnızca skaler işlenenler (örneğin, ADD aktivasyon skaleri) ve küçük tensör parametreleri (örneğin, RESHAPE şekil tensörü).
  • Ömür boyu CONSTANT_REFERENCE ise değerler model yapısının pools alanında bulunur. IPC sırasında ham değerlerin kopyalanması yerine yalnızca paylaşılan bellek havuzlarının tanıtıcıları çoğaltılır. Bu nedenle, büyük miktarda veriyi (örneğin, evrişimlerdeki ağırlık parametreleri) HIDL vektörlerine göre paylaşılan bellek havuzlarını kullanarak tutmak daha verimlidir.

Model yürütme zamanında, çerçeve sürücüye giriş ve çıkış işlenenlerinin arabelleklerini sağlar. Bir HIDL vektöründe gönderilebilen derleme zamanı sabitlerinin aksine, bir yürütmenin giriş ve çıkış verileri her zaman bir bellek havuzları koleksiyonu aracılığıyla iletilir.

HIDL veri türü hidl_memory eşlenmemiş bir paylaşılan bellek havuzunu temsil etmek için hem derlemede hem de yürütmede kullanılır. Sürücünün, hidl_memory veri türünün adına göre belleği kullanılabilir hale getirmek için belleği uygun şekilde eşlemesi gerekir. Desteklenen bellek adları şunlardır:

  • ashmem : Android'in paylaşılan hafızası. Daha fazla ayrıntı için bkz. hafıza .
  • mmap_fd : mmap aracılığıyla bir dosya tanımlayıcı tarafından desteklenen paylaşılan bellek.
  • hardware_buffer_blob : AHARDWARE_BUFFER_FORMAT_BLOB biçiminde bir AHardwareBuffer tarafından desteklenen paylaşılan bellek. Neural Networks (NN) HAL 1.2'den edinilebilir. Daha fazla ayrıntı için bkz. AHardwareBuffer .
  • hardware_buffer : AHARDWARE_BUFFER_FORMAT_BLOB biçimini kullanmayan genel bir AHardwareBuffer tarafından desteklenen paylaşılan bellek. BLOB olmayan mod donanım arabelleği yalnızca model yürütmede desteklenir. NN HAL 1.2'den edinilebilir. Daha fazla ayrıntı için bkz. AHardwareBuffer .

NN HAL 1.3'ten itibaren NNAPI, sürücü tarafından yönetilen arabellekler için ayırıcı arabirimler sağlayan bellek etki alanlarını destekler. Sürücü tarafından yönetilen arabellekler aynı zamanda yürütme girişleri veya çıkışları olarak da kullanılabilir. Daha fazla ayrıntı için bkz . Bellek alanları .

NNAPI sürücüleri, ashmem ve mmap_fd bellek adlarının eşlenmesini desteklemelidir. NN HAL 1.3'ten itibaren sürücülerin hardware_buffer_blob eşlemesini de desteklemesi gerekir. Genel BLOB olmayan mod hardware_buffer ve bellek etki alanları için destek isteğe bağlıdır.

ADonanım Tamponu

AHardwareBuffer, Gralloc arabelleğini saran bir tür paylaşılan bellektir. Android 10'da Neural Networks API (NNAPI), AHardwareBuffer kullanımını destekleyerek sürücünün verileri kopyalamadan yürütme gerçekleştirmesine olanak tanır ve bu da uygulamaların performansını ve güç tüketimini artırır. Örneğin, bir kamera HAL yığını, kamera NDK'sı ve medya NDK API'leri tarafından oluşturulan AHardwareBuffer tanıtıcılarını kullanarak makine öğrenimi iş yükleri için AHardwareBuffer nesnelerini NNAPI'ye iletebilir. Daha fazla bilgi için bkz. ANeuralNetworksMemory_createFromAHardwareBuffer .

NNAPI'de kullanılan AHardwareBuffer nesneleri, hardware_buffer veya hardware_buffer_blob adlı bir hidl_memory yapısı aracılığıyla sürücüye aktarılır. hidl_memory yapısı hardware_buffer_blob yalnızca AHARDWAREBUFFER_FORMAT_BLOB biçimindeki AHardwareBuffer nesnelerini temsil eder.

Çerçevenin gerektirdiği bilgiler hidl_memory yapısının hidl_handle alanına kodlanmıştır. hidl_handle alanı, AHardwareBuffer veya Gralloc arabelleği hakkında gerekli tüm meta verileri kodlayan native_handle öğesini sarar.

Sürücünün sağlanan hidl_handle alanının kodunu düzgün bir şekilde çözmesi ve hidl_handle tarafından tanımlanan belleğe erişmesi gerekir. getSupportedOperations_1_2 , getSupportedOperations_1_1 veya getSupportedOperations yöntemi çağrıldığında, sürücünün sağlanan hidl_handle kodunu çözüp çözemeyeceğini algılaması ve hidl_handle tarafından açıklanan belleğe erişip erişemeyeceğini algılaması gerekir. Sabit bir işlenen için kullanılan hidl_handle alanı desteklenmiyorsa model hazırlığı başarısız olmalıdır. Yürütmenin giriş veya çıkış işleneni için kullanılan hidl_handle alanı desteklenmiyorsa yürütme başarısız olmalıdır. Model hazırlığı veya yürütmesi başarısız olursa sürücünün bir GENERAL_FAILURE hata kodu döndürmesi önerilir.

Bellek alanları

Android 11 veya üstünü çalıştıran cihazlar için NNAPI, sürücü tarafından yönetilen arabellekler için ayırıcı arayüzler sağlayan bellek alanlarını destekler. Bu, aygıt yerel belleklerinin yürütmeler arasında aktarılmasına, gereksiz veri kopyalamanın ve aynı sürücüdeki ardışık yürütmeler arasında dönüşümün engellenmesine olanak tanır. Bu akış Şekil 1'de gösterilmektedir.

Bellek alanlarıyla ve bellek alanları olmadan arabellek veri akışı

Şekil 1. Bellek alanlarını kullanan tampon veri akışı

Bellek alanı özelliği, çoğunlukla sürücünün içinde bulunan ve istemci tarafında sık erişime ihtiyaç duymayan tensörler için tasarlanmıştır. Bu tür tensörlerin örnekleri arasında dizi modellerindeki durum tensörleri yer alır. İstemci tarafında sık sık CPU erişimine ihtiyaç duyan tensörler için, paylaşılan bellek havuzlarının kullanılması tercih edilir.

Bellek alanı özelliğini desteklemek için, çerçevenin sürücü tarafından yönetilen arabellek tahsisi talebinde bulunmasına izin vermek üzere IDevice::allocate uygulayın. Tahsis sırasında çerçeve, arabellek için aşağıdaki özellikleri ve kullanım modellerini sağlar:

  • BufferDesc arabelleğin gerekli özelliklerini açıklar.
  • BufferRole hazırlanan bir modelin girişi veya çıkışı olarak arabelleğin potansiyel kullanım modelini açıklar. Arabellek tahsisi sırasında birden fazla rol belirtilebilir ve tahsis edilen arabellek yalnızca belirtilen roller olarak kullanılabilir.

Tahsis edilen arabellek sürücünün içindedir. Bir sürücü herhangi bir arabellek konumunu veya veri düzenini seçebilir. Arabellek başarıyla tahsis edildiğinde, sürücünün istemcisi, döndürülen belirteci veya IBuffer nesnesini kullanarak arabelleğe başvurabilir veya arabellekle etkileşime girebilir.

IDevice::allocate gelen belirteç, ara belleğe bir yürütmenin Request yapısındaki MemoryPool nesnelerinden biri olarak başvurulduğunda sağlanır. Bir işlemin başka bir işlemde tahsis edilen arabelleğe erişmeye çalışmasını önlemek için sürücünün arabelleğin her kullanımında uygun doğrulamayı uygulaması gerekir. Sürücü, arabellek kullanımının tahsis sırasında sağlanan BufferRole rollerinden biri olduğunu doğrulamalı ve kullanımın yasa dışı olması durumunda yürütmeyi derhal başarısızlığa uğratmalıdır.

IBuffer nesnesi açık belleğe kopyalama için kullanılır. Belirli durumlarda, sürücünün istemcisi, sürücü tarafından yönetilen arabelleği paylaşılan bellek havuzundan başlatmalı veya arabelleği paylaşılan bellek havuzuna kopyalamalıdır. Örnek kullanım durumları şunları içerir:

  • Durum tensörünün başlatılması
  • Ara sonuçların önbelleğe alınması
  • CPU'da geri dönüş yürütme

Bu kullanım durumlarını desteklemek için sürücünün IBuffer::copyTo ve IBuffer::copyFrom ashmem , mmap_fd ve hardware_buffer_blob ile (bellek etki alanı tahsisini destekliyorsa) uygulaması gerekir. Sürücünün BLOB olmayan mod hardware_buffer desteklemesi isteğe bağlıdır.

Arabellek tahsisi sırasında, arabelleğin boyutları BufferRole tarafından belirtilen tüm rollerin karşılık gelen model işlenenlerinden ve BufferDesc sağlanan boyutlardan çıkarılabilir. Tüm boyutsal bilgilerin bir araya getirilmesiyle ara belleğin bilinmeyen boyutları veya sıralaması olabilir. Böyle bir durumda tampon, model girdisi olarak kullanıldığında boyutların sabit olduğu esnek bir durumda, model çıktısı olarak kullanıldığında ise dinamik durumdadır. Aynı arabellek, farklı uygulamalarda farklı çıkış şekilleriyle kullanılabilir ve sürücünün arabellek yeniden boyutlandırmasını doğru şekilde yapması gerekir.

Bellek alanı isteğe bağlı bir özelliktir. Bir sürücü, çeşitli nedenlerden dolayı belirli bir tahsis talebini destekleyemediğini belirleyebilir. Örneğin:

  • İstenen arabellek dinamik bir boyuta sahip.
  • Sürücünün büyük arabellekleri işlemesini engelleyen bellek kısıtlamaları var.

Sürücü tarafından yönetilen arabellekten aynı anda birkaç farklı iş parçacığının okunması mümkündür. Yazma veya okuma/yazma için ara belleğe aynı anda erişim tanımsızdır, ancak sürücü hizmetini çökertmemeli veya arayanı süresiz olarak engellememelidir. Sürücü bir hata döndürebilir veya arabellek içeriğini belirsiz bir durumda bırakabilir.