التخزين المؤقت للتجميع

من نظام التشغيل Android 10، أصبحت واجهة برمجة تطبيقات الشبكات العصبونية (NNAPI) توفر دوال لدعم التخزين المؤقت لعناصر التجميع، ما يقلّل من الوقت المُستغرَق في التجميع عند تشغيل التطبيق. وباستخدام وظيفة التخزين المؤقت هذه، لا إدارة أو مسح الملفات المخزنة مؤقتًا. هذه ميزة اختيارية يمكن تنفيذه باستخدام NN HAL 1.2. لمزيد من المعلومات حول هذه الدالة، الرؤية ANeuralNetworksCompilation_setCaching

يمكن لبرنامج التشغيل أيضًا تنفيذ التخزين المؤقت للتجميع البرمجي بشكل مستقل عن NNAPI. هذا النمط يمكن تنفيذها سواء تم استخدام ميزات التخزين المؤقت لـ NNAPI NDK وHAL أو لا. يوفر AOSP مكتبة من الخدمات منخفضة المستوى (محرك تخزين مؤقت). لمزيد من المعلومات، يُرجى الاطّلاع على تنفيذ محرك تخزين مؤقت.

نظرة عامة على سير العمل

يصف هذا القسم عمليات سير العمل العامة باستخدام ميزة التخزين المؤقت للتجميع تنفيذها.

تم تقديم معلومات ذاكرة التخزين المؤقت ونتيجة ذاكرة التخزين المؤقت

  1. يجتاز التطبيق دليل تخزين مؤقت ومجموع اختباري فريد للنموذج.
  2. يبحث بيئة تشغيل NNAPI عن ملفات ذاكرة التخزين المؤقت بناءً على المجموع الاختباري وتفضيل التنفيذ، ونتيجة التقسيم والعثور على الملفات.
  3. تفتح NNAPI ملفات ذاكرة التخزين المؤقت وتنقل المؤشرات إلى برنامج التشغيل. مع prepareModelFromCache
  4. يقوم برنامج التشغيل بإعداد النموذج مباشرة من ملفات ذاكرة التخزين المؤقت والإرجاع النموذج المعدّ.

تم تقديم معلومات ذاكرة التخزين المؤقت وذاكرة التخزين المؤقت غير موجودة

  1. يجتاز التطبيق مجموعًا اختباريًا فريدًا للنموذج والتخزين المؤقت الدليل.
  2. يبحث بيئة تشغيل NNAPI عن ملفات التخزين المؤقت بناءً على المجموع الاختباري وتفضيل التنفيذ، ونتيجة التقسيم ولم يعثر على ملفات ذاكرة التخزين المؤقت.
  3. تنشئ NNAPI ملفات ذاكرة تخزين مؤقت فارغة بناءً على المجموع الاختباري وعملية التنفيذ والتقسيم، وفتح ملفات ذاكرة التخزين المؤقت، وتمرير المقابض والنموذج إلى السائق مع prepareModel_1_2
  4. يجمع برنامج التشغيل النموذج ويكتب معلومات التخزين المؤقت في ذاكرة التخزين المؤقت. وترجع النموذج المعدّ.

لم يتم توفير معلومات ذاكرة التخزين المؤقت

  1. يستدعي التطبيق التجميع بدون توفير أي معلومات عن التخزين المؤقت.
  2. لا يعمل التطبيق على تمرير أي شيء مرتبط بالتخزين المؤقت.
  3. ويمرر وقت تشغيل NNAPI النموذج إلى برنامج التشغيل باستخدام prepareModel_1_2
  4. يقوم برنامج التشغيل بتجميع النموذج وعرض النموذج المعد.

معلومات ذاكرة التخزين المؤقت

تتكون معلومات التخزين المؤقت التي يتم تقديمها إلى السائق من رمز مؤشرات ملفات ذاكرة التخزين المؤقت.

الرمز المميز

تشير رسالة الأشكال البيانية الرمز المميّز هو رمز التخزين المؤقت للطول Constant::BYTE_SIZE_OF_CACHE_TOKEN تحدد النموذج المعدّ. ويتم توفير نفس الرمز عند حفظ في ذاكرة التخزين المؤقت باستخدام prepareModel_1_2 واسترداد النموذج الذي تم إعداده prepareModelFromCache يجب أن يختار عميل السائق رمزًا مميزًا بمعدل منخفض من التصادم. لا يمكن للسائق اكتشاف تضارب الرمز المميز. تصادم إلى فشل التنفيذ أو إلى عملية تنفيذ ناجحة نتج عنها قيم مخرجات غير صحيحة.

مؤشرات ملفات ذاكرة التخزين المؤقت (نوعان من ملفات ذاكرة التخزين المؤقت)

نوعا ملفات ذاكرة التخزين المؤقت هما ذاكرة التخزين المؤقت للبيانات وذاكرة التخزين المؤقت للنماذج.

  • ذاكرة التخزين المؤقت للبيانات: تُستخدم للتخزين المؤقت للبيانات الثابتة، بما في ذلك البيانات التي تمت معالجتها مسبقًا والمُحولات الاحتياطية إلى مترابطة. لا ينبغي إجراء تعديل على ذاكرة التخزين المؤقت ينتج عنه أي تأثير أسوأ من إنشاء قيم نتائج سيئة عند التنفيذ الوقت.
  • ذاكرة التخزين المؤقت للنموذج: تُستخدم للتخزين المؤقت للبيانات الحساسة للأمان، مثل البيانات المجمّعة رمز الجهاز القابل للتنفيذ بالتنسيق الثنائي الأصلي للجهاز. حاسمة قد يؤثر تعديل ذاكرة التخزين المؤقت للنموذج على تنفيذ برنامج التشغيل ويمكن أن يستفيد عميل ضار من هذه الطريقة لتنفيذ ما بعد الإذن الممنوح. وبالتالي، يجب أن يتحقق برنامج التشغيل مما إذا كانت ذاكرة التخزين المؤقت للنموذج قبل إعداد النموذج من ذاكرة التخزين المؤقت. لمزيد من المعلومات راجِع الأمان.

يجب أن يحدد برنامج التشغيل كيفية توزيع معلومات ذاكرة التخزين المؤقت بين الاثنين وأنواع ملفات ذاكرة التخزين المؤقت والإبلاغ عن عدد ملفات ذاكرة التخزين المؤقت اللازمة لكل نوع مع getNumberOfCacheFilesNeeded

يفتح بيئة تشغيل NNAPI دائمًا مؤشرات ملفات ذاكرة التخزين المؤقت التي تتضمّن كلاً من القراءة والكتابة إذن.

الأمان

أثناء التخزين المؤقت للتجميع، قد تحتوي ذاكرة التخزين المؤقت للنموذج على بيانات حساسة للأمان مثل كرمز برمجي جهاز قابل للتنفيذ مجمّع بالتنسيق الثنائي الأصلي للجهاز. إذا لم يكن كذلك محمي بشكل صحيح، فإن تعديل ذاكرة التخزين المؤقت للطراز قد يؤثر على تخزين والتنفيذ. لأنّه يتم تخزين محتوى ذاكرة التخزين المؤقت في التطبيق الدليل، تكون ملفات ذاكرة التخزين المؤقت قابلة للتعديل بواسطة العميل. قد يقوم العميل البالون يؤدي إلى تلف ذاكرة التخزين المؤقت عن طريق الخطأ، وقد يتسبب أحد البرامج الضارة في حدوث استخدام هذا الإجراء لتنفيذ رمز لم يتم التحقّق منه على الجهاز. استنادًا إلى خصائص الجهاز، فربما تكون هناك مشكلة أمنية. وبالتالي، يجب أن يكون السائق قادرًا على اكتشاف احتمال تلف في ذاكرة التخزين المؤقت للنموذج قبل إعداد النموذج من ذاكرة التخزين المؤقت.

تتمثل إحدى طرق القيام بذلك في أن يحافظ السائق على خريطة بدءًا من الرمز المميز التجزئة المشفرة لذاكرة التخزين المؤقت للنموذج. يمكن للسائق تخزين الرمز المميز تجزئة ذاكرة التخزين المؤقت للنموذج الخاص به عند حفظ التحويل البرمجي إلى ذاكرة التخزين المؤقت. عمليات فحص السائق التجزئة الجديدة لذاكرة التخزين المؤقت للنموذج مع الرمز المميز المسجل وزوج التجزئة عند استرداد التحويل البرمجي من ذاكرة التخزين المؤقت. يجب أن يكون هذا التعيين ثابتًا عبر عمليات إعادة تشغيل النظام. يمكن للسائق استخدام خدمة ملف تخزين مفاتيح Android، وهي مكتبة الأدوات المساعدة في framework/ml/nn/driver/cache، أو أي آلية أخرى مناسبة لتنفيذ مدير الخرائط. عند السائق يجب إعادة إعداد مدير التعيين هذا لمنع إعداد ذاكرة التخزين المؤقت من إصدار سابق.

لمنع وقت التحقّق من وقت الاستخدام (TOCTOU)، على برنامج التشغيل حساب التجزئة المسجلة قبل الحفظ في وتحسب التجزئة الجديدة بعد نسخ محتوى الملف إلى قسم المورد الاحتياطي.

يوضح نموذج التعليمة البرمجية هذا كيفية تنفيذ هذا المنطق.

bool saveToCache(const sp<V1_2::IPreparedModel> preparedModel,
                 const hidl_vec<hidl_handle>& modelFds, const hidl_vec<hidl_handle>& dataFds,
                 const HidlToken& token) {
    // Serialize the prepared model to internal buffers.
    auto buffers = serialize(preparedModel);

    // This implementation detail is important: the cache hash must be computed from internal
    // buffers instead of cache files to prevent time-of-check to time-of-use (TOCTOU) attacks.
    auto hash = computeHash(buffers);

    // Store the {token, hash} pair to a mapping manager that is persistent across reboots.
    CacheManager::get()->store(token, hash);

    // Write the cache contents from internal buffers to cache files.
    return writeToFds(buffers, modelFds, dataFds);
}

sp<V1_2::IPreparedModel> prepareFromCache(const hidl_vec<hidl_handle>& modelFds,
                                          const hidl_vec<hidl_handle>& dataFds,
                                          const HidlToken& token) {
    // Copy the cache contents from cache files to internal buffers.
    auto buffers = readFromFds(modelFds, dataFds);

    // This implementation detail is important: the cache hash must be computed from internal
    // buffers instead of cache files to prevent time-of-check to time-of-use (TOCTOU) attacks.
    auto hash = computeHash(buffers);

    // Validate the {token, hash} pair by a mapping manager that is persistent across reboots.
    if (CacheManager::get()->validate(token, hash)) {
        // Retrieve the prepared model from internal buffers.
        return deserialize<V1_2::IPreparedModel>(buffers);
    } else {
        return nullptr;
    }
}

حالات الاستخدام المتقدّمة

في بعض حالات الاستخدام المتقدمة، يحتاج السائق إلى الوصول إلى محتوى ذاكرة التخزين المؤقت (قراءة أو كتابة) بعد مكالمة التجميع. تشمل أمثلة حالات الاستخدام ما يلي:

  • تجميع المحتوى في الوقت المناسب: يتأخّر الفيديو التجميعي حتى والتنفيذ الأول.
  • تجميع الفيديو المجمّع من عدة مراحل: يتم في البداية تجميع المحتوى بشكل سريع. ويتم تنفيذ تجميع اختياري محسّن في وقت لاحق اعتمادًا على تكرار الاستخدام.

للوصول إلى محتوى ذاكرة التخزين المؤقت (قراءة أو كتابة) بعد المكالمة التجميعية، تأكد من أن السائق:

  • يتم تكرار الأسماء المعرِّفة للملفات أثناء استدعاء prepareModel_1_2 أو prepareModelFromCache وقراءة/تعديل ذاكرة التخزين المؤقت المحتوى في وقت لاحق.
  • تنفيذ منطق قفل الملف خارج استدعاء التجميع العادي لمنع حدوث الكتابة بالتزامن مع قراءة أو كتابة أخرى.

تنفيذ محرك التخزين المؤقت

بالإضافة إلى واجهة التخزين المؤقت للتجميعات NN HAL 1.2، يمكنك أيضًا العثور على للتخزين المؤقت في مكتبة frameworks/ml/nn/driver/cache الدليل. تشير رسالة الأشكال البيانية nnCache يحتوي دليل فرعي على رمز تخزين ثابت لبرنامج التشغيل لينفّذه. التخزين المؤقت للتجميع بدون استخدام ميزات التخزين المؤقت في NNAPI. يُعد هذا الشكل من يمكن تنفيذ التخزين المؤقت للتجميع مع أي إصدار من NN HAL. إذا كانت اختيار برنامج التشغيل تنفيذ التخزين المؤقت غير المرتبط بواجهة HAL، السائق مسئولاً عن تحرير العناصر المخزنة مؤقتًا عندما لا تكون هناك حاجة إليها.