Bellek havuzları

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

Çerçeve, model derleme sırasında sabit işlenenlerin değerlerini sürücüye sağlar. Sabit işlenenin kullanım ömrüne bağlı olarak değerleri HIDL vektöründe veya paylaşılan bellek havuzunda bulunur.

  • Yaşam süresi CONSTANT_COPY ise değerler model yapısının operandValues alanında yer alır. HIDL vektöründeki değerler, süreçler arası iletişim (IPC) sırasında kopyalandığından bu genellikle yalnızca skaler işlenenler (ör. ADD içindeki etkinleştirme skaler değeri) ve küçük tensör parametreleri (ör. RESHAPE içindeki şekil tensörü) gibi az miktarda veriyi tutmak için kullanılır.
  • Yaşam süresi CONSTANT_REFERENCE ise değerler model yapısının pools alanında yer alır. IPC sırasında, ham değerler kopyalanmak yerine yalnızca paylaşılan bellek havuzlarının tutamaçları çoğaltılır. Bu nedenle, büyük miktarda veriyi (örneğin, konvolüsyonlardaki ağırlık parametreleri) HIDL vektörleri yerine paylaşılan bellek havuzlarını kullanarak tutmak daha verimlidir.

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

HIDL veri türü hidl_memory, eşlenmemiş bir paylaşılan bellek havuzunu temsil etmek için hem derleme hem de yürütme sırasında kullanılır. Sürücü, hidl_memory veri türünün adına göre kullanılabilir hale getirmek için belleği buna göre eşlemelidir. Desteklenen bellek adları şunlardır:

  • ashmem: Android paylaşılan anı. Daha fazla bilgi için bellek başlıklı makaleyi inceleyin.
  • mmap_fd: mmap aracılığıyla dosya tanımlayıcısı tarafından desteklenen paylaşılan bellek.
  • hardware_buffer_blob: Biçimi AHARDWARE_BUFFER_FORMAT_BLOB olan bir AHardwareBuffer ile desteklenen paylaşılan bellek. Neural Networks (NN) HAL 1.2'den itibaren kullanılabilir. Daha fazla bilgi için AHardwareBuffer başlıklı makaleyi inceleyin.
  • hardware_buffer: AHARDWARE_BUFFER_FORMAT_BLOB biçimini kullanmayan genel bir AHardwareBuffer tarafından desteklenen paylaşılan bellek. BLOB dışı mod donanım arabelleği yalnızca model yürütmede desteklenir.NN HAL 1.2'den itibaren kullanılabilir. Daha fazla bilgi için AHardwareBuffer başlıklı makaleyi inceleyin.

NN HAL 1.3'ten itibaren NNAPI, sürücü tarafından yönetilen arabellekler için ayırıcı arayüzleri sağlayan bellek alanlarını destekler. Sürücü tarafından yönetilen arabellekler, yürütme girişleri veya çıkışları olarak da kullanılabilir. Daha fazla bilgi için Bellek alanları başlıklı makaleyi inceleyin.

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 dışı mod hardware_buffer ve bellek alanları için destek isteğe bağlıdır.

AHardwareBuffer

AHardwareBuffer, bir Gralloc arabelleğini sarmalayan bir paylaşılan bellek türüdür. Android 10'da Neural Networks API (NNAPI), AHardwareBuffer kullanımını destekler. Bu sayede sürücü, verileri kopyalamadan yürütme işlemleri gerçekleştirebilir. Bu da uygulamaların performansını ve güç tüketimini iyileştirir. Örneğin, bir kamera HAL yığını, kamera NDK ve medya NDK API'leri tarafından oluşturulan AHardwareBuffer tutamaçlarını kullanarak makine öğrenimi iş yükleri için AHardwareBuffer nesnelerini NNAPI'ye iletebilir. Daha fazla bilgi için ANeuralNetworksMemory_createFromAHardwareBuffer konusuna bakın.

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

Çerçeve tarafından gerekli olan bilgiler, hidl_memory yapısının hidl_handle alanında kodlanır. hidl_handle alanı, AHardwareBuffer veya Gralloc arabelleğiyle ilgili gerekli tüm meta verileri kodlayan native_handle sarmalar.

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

Anı alanları

Android 11 veya sonraki sürümlerin yüklü olduğu cihazlarda NNAPI, sürücü tarafından yönetilen arabellekler için ayırıcı arayüzleri sağlayan bellek alanlarını destekler. Bu sayede, cihazın yerel bellekleri yürütmeler arasında aktarılabilir ve aynı sürücüdeki ardışık yürütmeler arasında gereksiz veri kopyalama ve dönüştürme işlemleri engellenebilir. Bu akış, Şekil 1'de gösterilmektedir.

Bellek alanlarıyla ve bellek alanları olmadan veri akışını arabelleğe alma

1. şekil. Bellek alanlarını kullanarak veri akışını arabelleğe alma

Bellek alanı özelliği, çoğunlukla sürücüye ait olan ve istemci tarafında sık erişim gerektirmeyen tensörler için tasarlanmıştır. Bu tür tensörlere örnek olarak sıralı modellerdeki durum tensörleri verilebilir. İstemci tarafında sık sık CPU erişimi gerektiren tensörler için paylaşılan bellek havuzlarının kullanılması tercih edilir.

Bellek alanı özelliğini desteklemek için IDevice::allocate uygulayın. Bu, çerçevenin sürücü tarafından yönetilen arabellek ayırma isteğinde bulunmasına olanak tanır. Çerçeve, ayırma sırasında arabellek için aşağıdaki özellikleri ve kullanım kalıplarını sağlar:

  • BufferDesc arabellek için gerekli özellikleri açıklar.
  • BufferRole arabelleğin, hazırlanmış bir modelin girişi veya çıkışı olarak potansiyel kullanım şeklini açıklar. Arabellek ayırma sırasında birden fazla rol belirtilebilir ve ayrılan arabellek yalnızca belirtilen roller olarak kullanılabilir.

Ayrılan arabellek sürücüye özeldir. Sürücü, herhangi bir arabellek konumu veya veri düzeni seçebilir. Arabellek başarıyla ayrıldığında, sürücünün istemcisi, döndürülen jetonu veya IBuffer nesnesini kullanarak arabelleğe başvurabilir ya da arabellekle etkileşim kurabilir.

Arabellek, bir yürütmenin Request yapısındaki MemoryPool nesnelerinden biri olarak referans verildiğinde IDevice::allocate'dan alınan jeton sağlanır. Bir işlemin başka bir işlemde ayrılan arabelleğe erişmeye çalışmasını önlemek için sürücü, arabelleğin her kullanımında uygun doğrulamayı uygulamalıdır. Sürücü, arabellek kullanımının ayırma sırasında sağlanan BufferRole rollerinden biri olduğunu doğrulamalı ve kullanım yasa dışıysa yürütmeyi hemen durdurmalıdır.

IBuffer nesnesi, açık bellek kopyalama için kullanılır. Bazı durumlarda, sürücünün istemcisi, sürücü tarafından yönetilen arabelleği paylaşılan bir bellek havuzundan başlatmalı veya arabelleği paylaşılan bir bellek havuzuna kopyalamalıdır. Kullanım alanı örnekleri:

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

Bu kullanım alanlarını desteklemek için sürücü, bellek alanı ayırmayı destekliyorsa IBuffer::copyTo ve IBuffer::copyFrom ile ashmem, mmap_fd ve hardware_buffer_blob'u uygulamalıdır. Sürücünün BLOB olmayan modu desteklemesi isteğe bağlıdır hardware_buffer.

Arabellek ayırma sırasında, arabelleğin boyutları BufferRole ile belirtilen tüm rollerin ilgili model işlenenlerinden ve BufferDesc içinde sağlanan boyutlardan çıkarılabilir. Tüm boyut bilgileri birleştirildiğinde arabellekte bilinmeyen boyutlar veya sıralama olabilir. Bu gibi durumlarda arabellek, model girişi olarak kullanıldığında boyutların sabit olduğu esnek bir durumda, model çıkışı olarak kullanıldığında ise dinamik bir durumda olur. Aynı arabellek, farklı yürütmelerde farklı şekillerdeki çıkışlarla kullanılabilir ve sürücü, arabellek yeniden boyutlandırmasını düzgün şekilde işlemelidir.

Bellek alanı isteğe bağlı bir özelliktir. Bir sürücü, çeşitli nedenlerle belirli bir ayırma isteğini destekleyemeyeceğ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ı vardır.

Sürücü tarafından yönetilen arabellekten aynı anda birden fazla farklı iş parçacığı okuyabilir. Yazma veya okuma/yazma için arabelleğe aynı anda erişmek tanımlanmamıştır ancak sürücü hizmetinin kilitlenmesine veya arayanın süresiz olarak engellenmesine neden olmamalıdır. Sürücü bir hata döndürebilir veya arabelleğin içeriğini belirsiz bir durumda bırakabilir.