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ınoperandValues
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ınpools
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çimiAHARDWARE_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.
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.