HIDL মেমরি ব্লক

HIDL MemoryBlock হলো hidl_memory , HIDL @1.0::IAllocator , এবং HIDL @1.0::IMapper উপর নির্মিত একটি অ্যাবস্ট্রাক্ট লেয়ার। এটি এমন HIDL সার্ভিসগুলোর জন্য ডিজাইন করা হয়েছে, যেগুলোর একাধিক মেমরি ব্লক একটিমাত্র মেমরি হিপ শেয়ার করে।

কর্মক্ষমতার উন্নতি

অ্যাপে MemoryBlock ব্যবহার করলে mmap / munmap এবং ইউজার স্পেস সেগমেন্টেশন ফল্টের সংখ্যা উল্লেখযোগ্যভাবে হ্রাস পায়, ফলে পারফরম্যান্স উন্নত হয়। উদাহরণস্বরূপ:

  • প্রতিটি বাফার অ্যালোকেশনের জন্য hidl_memory প্রতি গড়ে ২৩৮ মাইক্রোসেকেন্ড/১ অ্যালোকেশন খরচ হয়।
  • MemoryBlock ব্যবহার করে এবং একটিমাত্র hidl_memory শেয়ার করলে প্রতি অ্যালোকেশনে গড়ে ২.৮২ মাইক্রোসেকেন্ড খরচ হয়।

স্থাপত্য

HIDL MemoryBlock আর্কিটেকচারে এমন HIDL পরিষেবা অন্তর্ভুক্ত রয়েছে যেখানে একাধিক মেমোরি ব্লক একটিমাত্র মেমোরি হিপ শেয়ার করে:

HIDL মেমোরিব্লক

চিত্র ১. HIDL মেমোরিব্লক স্থাপত্য

সাধারণ ব্যবহার

এই অংশে প্রথমে HAL ঘোষণা করে এবং তারপর তা বাস্তবায়ন করে MemoryBlock ব্যবহারের একটি উদাহরণ দেওয়া হয়েছে।

HAL ঘোষণা করুন

নিম্নলিখিত উদাহরণ IFoo HAL এর জন্য:

import android.hidl.memory.block@1.0::MemoryBlock;

interface IFoo {
    getSome() generates(MemoryBlock block);
    giveBack(MemoryBlock block);
};

Android.bp নিম্নরূপ:

hidl_interface {
    ...
    srcs: [
        "IFoo.hal",
    ],
    interfaces: [
        "android.hidl.memory.block@1.0",
        ...
};

HAL বাস্তবায়ন করুন

HAL উদাহরণটি বাস্তবায়ন করতে:

  1. hidl_memory টি নিন (বিস্তারিত জানতে HIDL C++ দেখুন)।

    #include <android/hidl/allocator/1.0/IAllocator.h>
    
    using ::android::hidl::allocator::V1_0::IAllocator;
    using ::android::hardware::hidl_memory;
    ...
      sp<IAllocator> allocator = IAllocator::getService("ashmem");
      >allocator-alloca&te(2048, [](bool success, const h&idl_memory mem)
      {
            if (!success) { /* error */ }
            // you can now use the hidl_memory object 'mem' or pass it
      }));
    
  2. অর্জিত hidl_memory ব্যবহার করে একটি HidlMemoryDealer ইনস্ট্যান্স তৈরি করুন:

    #include <hidlmemory/HidlMemoryDealer.h>
    
    using ::android::hardware::HidlMemoryDealer
    /* The mem argument is acquired in the Step1, returned by the ashmemAllocator->allocate */
    sp<HidlMemoryDealer> memory_dealer = HidlMemoryDealer::getInstance(mem);
    
  3. MemoryBlock বরাদ্দ করুন, যা HIDL দিয়ে সংজ্ঞায়িত একটি struct।

    উদাহরণ MemoryBlock :

    struct MemoryBlock {
    IMemoryToken token;
    uint64_t size;
    uint64_t offset;
    };
    

    MemoryDealer ব্যবহার করে MemoryBlock বরাদ্দ করার উদাহরণ:

    #include <android/hidl/memory/block/1.0/types.h>
    
    using ::android::hidl::memory::block::V1_0::MemoryBlock;
    
    Return<void> Foo::getSome(getSome_cb _hidl_cb) {
        MemoryBlock block = memory_dealer->allocate(1024);
        if(HidlMemoryDealer::isOk(block)){
            _hidl_cb(block);
        ...
    
  4. MemoryBlock মুক্ত করুন :

    Return<void> Foo::giveBack(const MemoryBlock& block) {
        memory_dealer->deallocate(block.offset);
    ...
    
  5. ডেটা পরিচালনা করুন:

    #include <hidlmemory/mapping.h>
    #include <android/hidl/memory/1.0/IMemory.h>
    
    using ::android::hidl::memory::V1_0::IMemory;
    
    sp<IMemory> memory = mapMemory(block);
    uint8_t* data =
    
    static_cast<uint8_t*>(static_cast<void*>(memory->getPointer()));
    
  6. Config Android.bp :

    shared_libs: [
            "android.hidl.memory@1.0",
    
            "android.hidl.memory.block@1.0"
    
            "android.hidl.memory.token@1.0",
            "libhidlbase",
            "libhidlmemory",
    
  7. আপনার lockMemory প্রয়োজন আছে কিনা তা নির্ধারণ করতে কার্যপ্রবাহটি পর্যালোচনা করুন।

    সাধারণত, MemoryBlock তার শেয়ার্ড hidl_memory বজায় রাখার জন্য রেফারেন্স কাউন্ট ব্যবহার করে, যা এর কোনো MemoryBlock instances is mapped and is mmap() -ed হয় এবং -ed when nothing refers to it. To keep always mapped, you can use , a RAII style object that keeps the corresponding । উদাহরণ:

    #include <hidlmemory/mapping.h>
    
    sp<RefBase> lockMemory(const sp<IMemoryToken> key);
    

বর্ধিত ব্যবহার

এই অংশে MemoryBlock এর বর্ধিত ব্যবহার সম্পর্কে বিস্তারিত আলোচনা করা হয়েছে।

মেমোরিব্লক পরিচালনা করতে রেফারেন্স কাউন্ট ব্যবহার করুন

বেশিরভাগ ক্ষেত্রে, MemoryBlock ব্যবহারের সবচেয়ে কার্যকর উপায় হলো স্পষ্টভাবে মেমরি বরাদ্দ বা মুক্ত করা। তবে, জটিল অ্যাপের ক্ষেত্রে গার্বেজ কালেকশনের জন্য রেফারেন্স কাউন্ট ব্যবহার করা আরও ভালো উপায় হতে পারে। MemoryBlock এ রেফারেন্স কাউন্ট চালু রাখতে, আপনি একটি বাইন্ডার অবজেক্টের সাথে MemoryBlock বাইন্ড করতে পারেন, যা রেফারেন্সগুলো গণনা করতে এবং গণনার সংখ্যা শূন্যে নেমে এলে MemoryBlock মুক্ত করতে সাহায্য করে।

HAL ঘোষণা করুন

HAL ঘোষণা করার সময়, একটি HIDL struct বর্ণনা করুন যাতে একটি MemoryBlock ইনস্ট্যান্স এবং একটি IBase থাকে:

import android.hidl.memory.block@1.0::MemoryBlock;

struct MemoryBlockAllocation {
    MemoryBlock block;
    IBase refcnt;
};

MemoryBlock প্রতিস্থাপন করতে MemoryBlockAllocation ব্যবহার করুন এবং MemoryBlock ফেরত দেওয়ার জন্য মেথডটি সরিয়ে দিন। MemoryBlockAllocation এর মাধ্যমে রেফারেন্স কাউন্টিং করে এটিকে ডিলোকেট করা হয়। উদাহরণ:

interface IFoo {
    allocateSome() generates(MemoryBlockAllocation allocation);
};

HAL বাস্তবায়ন করুন

HAL-এর সার্ভিস সাইড বাস্তবায়নের উদাহরণ:

class MemoryBlockRefCnt: public virtual IBase {
   MemoryBlockRefCnt(uint64_t offset, sp<MemoryDealer> dealer)
     : mOffset(offset), mDealer(dealer) {}
   ~MemoryBlockRefCnt() {
       mDealer->deallocate(mOffset);
   }
 private:
   uint64_t mOffset;
   sp<MemoryDealer> mDealer;
};

Return<void> Foo::allocateSome(allocateSome_cb _hidl_cb) {
    MemoryBlockAllocation allocation;
    allocation.block = memory_dealer->allocate(1024);
    if(HidlMemoryDealer::isOk(block)){
        allocation.refcnt= new MemoryBlockRefCnt(...);
        _hidl_cb(allocation);

HAL-এর ক্লায়েন্ট সাইড বাস্তবায়নের উদাহরণ:

ifoo->allocateSome([&](const MemoryBlockAllocation& allocation){
    ...
);

মেটাডেটা সংযুক্ত করুন এবং পুনরুদ্ধার করুন

কিছু অ্যাপকে বরাদ্দকৃত MemoryBlock সাথে বাইন্ড করার জন্য অতিরিক্ত ডেটার প্রয়োজন হয়। আপনি দুটি পদ্ধতি ব্যবহার করে মেটাডেটা যুক্ত এবং পুনরুদ্ধার করতে পারেন:

  • অ্যাপটি যদি ব্লকটির মতোই প্রায়শই মেটাডেটা অ্যাক্সেস করে, তাহলে মেটাডেটা অ্যাপেন্ড করুন এবং সেগুলোকে একটি স্ট্রাক্ট-এর মধ্যে পাস করুন। উদাহরণ:

    import android.hidl.memory.block@1.0::MemoryBlock;
    
    struct MemoryBlockWithMetaData{
        MemoryBlock block;
        MetaDataStruct metaData;
    };
    
  • যদি অ্যাপটি ব্লকের তুলনায় মেটাডেটা অনেক কম ব্যবহার করে, তবে একটি ইন্টারফেসের মাধ্যমে পরোক্ষভাবে মেটাডেটা প্রেরণ করা অধিক কার্যকর। উদাহরণ:

    import android.hidl.memory.block@1.0::MemoryBlock;
    
    struct MemoryBlockWithMetaData{
        MemoryBlock block;
        IMetaData metaData;
    };
    

    এরপরে, MemoryDealer ব্যবহার করে MemoryBlock এর সাথে মেটাডেটা সংযুক্ত করুন। উদাহরণ:

    MemoryBlockWithMetaData memory_block;
    memory_block.block = dealer->allocate(size);
    if(HidlMemoryDealer::isOk(block)){
        memory_block.metaData = new MetaData(...);