التحسين الموجّه إلى الملف الشخصي (PGO) هو أسلوب معروف أيضًا لتحسين برامج التجميع. في PGO، تُستخدم الملفات الشخصية لوقت التشغيل من عمليات تنفيذ البرنامج من قبل برنامج التجميع لتحديد الخيارات المثلى حول التنسيق المضمّن وتخطيط التعليمات البرمجية. يؤدّي ذلك إلى تحسين الأداء وتقليل حجم الرمز البرمجي.
يمكن نشر ميزة "التحسين أثناء التشغيل" في تطبيقك أو مكتبتك باتّباع الخطوات التالية: 1. حدد عبء العمل التمثيلي. 2- جمع الملفات الشخصية 3- استخدام الملفات الشخصية في إصدار الإصدار
الخطوة 1: تحديد حجم عمل نموذجي
أولاً، حدِّد معيارًا ممثّلاً أو حجم عمل لتطبيقك. هذه خطوة حاسمة لأنّ الملفات الشخصية التي يتم جمعها من أعباء العمل تحدّد المناطق الرائجة والمناطق الأقل استخدامًا في الرمز البرمجي. عند استخدام الملفات الشخصية، سينفِّذ المُجمِّع تحسينات مكثّفة وعمليات تضمين في المناطق التي تُستخدم بشكل كبير. قد يختار المُجمِّع أيضًا تقليل حجم الرمز البرمجي للمناطق التي لا يتمّ استخدامها كثيرًا مع التضحية بالأداء.
من المفيد أيضًا تحديد عبء عمل جيد لتتبُّع الأداء بشكلٍ عام.
الخطوة 2: جمع الملفات الشخصية
تتضمّن عملية جمع الملفات الشخصية ثلاث خطوات: - إنشاء رمز برمجي أصلي باستخدام أدوات القياس، - تشغيل التطبيق الذي تمّت أدوات القياس له على الجهاز وإنشاء الملفات الشخصية، - دمج الملفات الشخصية أو معالجتها بعد اكتمالها على المضيف.
إنشاء إصدار يتضمّن أدوات قياس الأداء
يتم جمع الملفات الشخصية عن طريق تشغيل عبء العمل من الخطوة 1 في
إصدار مساعِد للتطبيق. لإنشاء إصدار تمّت تهيئته، أضِف -fprofile-generate إلى علامات المُجمِّع والرابط. يجب أن يتم التحكّم في هذه العلامة
باستخدام متغيّر إنشاء منفصل لأنّ العلامة غير مطلوبة أثناء عملية الإنشاء
التلقائية.
إنشاء الملفات الشخصية
بعد ذلك، شغِّل تطبيق قياس حالة التطبيق على الجهاز وأنشئ ملفات شخصية.
يتم جمع الملفات الشخصية في الذاكرة عند تشغيل البرنامج الثنائي الذي تم قياسه، ثم كتابته في ملف عند الخروج. ومع ذلك، لا يتم استدعاء الوظائف المسجَّلة في atexit
في أحد تطبيقات Android، بل يتم إيقافها نهائيًا.
على التطبيق أو حمولة العمل تنفيذ عمل إضافي لضبط مسار لملف الملف الشخصي ثم بدء عملية كتابة ملف التعريف بشكل صريح.
- لضبط مسار ملفّ الملف الشخصي، يمكنك طلب
__llvm_profile_set_filename(PROFILE_DIR "/default-%m.profraw. يكون الخيار%mمفيدًا عند توفُّر عدة مكتبات مشتركة. يتم توسيع%mإلى توقيع وحدة فريد لتلك المكتبة، ما يؤدي إلى إنشاء ملف شخصي منفصل لكل مكتبة. يمكنك الاطّلاع على هذا الرابط للحصول على معلومات عن محددات الأنماط المفيدة الأخرى.PROFILE_DIRهو دليل يمكن كتابته من التطبيق. اطّلِع على العرض التوضيحي لرصد هذا الدليل أثناء التشغيل. - لبدء عملية كتابة ملف شخصي بشكل صريح، استخدِم الدالة
__llvm_profile_write_file.
extern "C" {
extern int __llvm_profile_set_filename(const char*);
extern int __llvm_profile_write_file(void);
}
#define PROFILE_DIR "<location-writable-from-app>"
void workload() {
// ...
// run workload
// ...
// set path and write profiles after workload execution
__llvm_profile_set_filename(PROFILE_DIR "/default-%m.profraw");
__llvm_profile_write_file();
return;
}
ملاحظة: يكون إنشاء ملف الملف الشخصي أسهل إذا كانت حمولة العمل ملفًا ثنائيًا مستقلاً.
ما عليك سوى ضبط متغيّر البيئة LLVM_PROFILE_FILE على %t/default-%m.profraw
قبل تشغيل الملف الثنائي.
الملفات الشخصية للمعالجة اللاحقة
تكون ملفات الملفات الشخصية بتنسيق .profraw. يجب أولاً جلبها من
الجهاز باستخدام adb pull. بعد جلب الملف، استخدِم الأداة llvm-profdata في
حزمة NDK للتحويل من .profraw إلى .profdata، ويمكن بعد ذلك تمريرها إلى
المجمِّع.
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/llvm-profdata \
merge --output=pgo_profile.profdata \
<list-of-profraw-files>
استخدِم llvm-profdata وclang من إصدار NDK نفسه لتجنُّب عدم تطابق التنسيق
لملف التعريف.
الخطوة 3: استخدام الملفات الشخصية لإنشاء التطبيق
استخدِم الملف الشخصي من الخطوة السابقة أثناء إنشاء إصدار من
تطبيقك من خلال تمرير -fprofile-use=<>.profdata إلى المُجمِّع والرابط. يمكن استخدامملفّات الprofile حتى أثناء تطوير الرمز البرمجي، إذ يمكن لمجمّع Clang تحمل عدم تطابق بسيط بين المصدر وملفات الprofile.
ملاحظة: بشكل عام، تكون الملفات الشخصية شائعة في معظم المكتبات على مستوى جميع التصاميم. على سبيل المثال، يمكن استخدام الملفات الشخصية التي تم إنشاؤها من إصدار arm64 من المكتبة لجميع التصاميم. نود تذكيرك بأنّه في حال توفُّر مسارات تعليمات برمجية خاصة بالبنية في المكتبة (الذراع مقابل x86 أو 32 بت مقابل 64 بت)، يجب استخدام ملفات شخصية منفصلة لكل إعداد من هذا النوع.
خلاصة ما سبق ذكره
يعرض الرابط https://github.com/DanAlbert/ndk-samples/tree/pgo/pgo عرضًا توضيحيًا شاملاً لاستخدام أداة PGO من تطبيق، كما يقدّم تفاصيل إضافية لم تتم الإشارة إليها في هذا المستند.
- توضح قواعد إنشاء CMake كيفية إعداد متغير CMake الذي ينشئ رمزًا أصليًا باستخدام الأدوات. في حال عدم ضبط متغيّر الإنشاء، يتم تحسين الرمز البرمجي الأصلي باستخدام ملفات تعريف PGO التي تم إنشاؤها سابقًا.
- في الإصدار الذي تم اختباره، يُسجِّلملف pgodemo.cppملفّات الأداء التي تُنفِّذ أعباء العمل.
- يتم الحصول على موقع قابل للكتابة للملفات الشخصية أثناء التشغيل فيملف MainActivity.kt باستخدام
applicationContext.cacheDir.toString(). - لسحب الملفات الشخصية من الجهاز بدون الحاجة إلى
adb root، استخدِمadbالوصفهنا.