प्रोफ़ाइल के हिसाब से ऑप्टिमाइज़ेशन

प्रोफ़ाइल के हिसाब से ऑप्टिमाइज़ेशन (पीजीओ) एक जाना-माना कंपाइलर ऑप्टिमाइज़ेशन है तकनीक. PGO में, प्रोग्राम के तहत लागू होने वाले रनटाइम प्रोफ़ाइलों का इस्तेमाल कंपाइलर, इनलाइनिंग और कोड लेआउट के बारे में सबसे सही विकल्प चुन सकता है. इससे यह होता है इसकी परफ़ॉर्मेंस बेहतर होती है और कोड का साइज़ कम होता है.

यहां दिए गए तरीके का इस्तेमाल करके, पीजीओ को आपके ऐप्लिकेशन या लाइब्रेरी में डिप्लॉय किया जा सकता है: 1. प्रतिनिधि के वर्कलोड की पहचान करें. 2. प्रोफ़ाइलें इकट्ठा करना. 3. किसी रिलीज़ बिल्ड में प्रोफ़ाइलों का इस्तेमाल करना.

पहला चरण: प्रतिनिधि के तौर पर वर्कलोड की पहचान करना

सबसे पहले, अपने ऐप्लिकेशन के लिए प्रतिनिधि मानदंड या वर्कलोड की पहचान करें. यह एक अहम चरण है, क्योंकि वर्कलोड से इकट्ठा की गई प्रोफ़ाइल कोड में गर्म और ठंडे क्षेत्र की कैटगरी चुनें. प्रोफ़ाइलों का इस्तेमाल करते समय, कंपाइलर गर्म इलाकों में एग्रेसिव ऑप्टिमाइज़ेशन और इनलाइनिंग करते हैं. द कंपाइलर ट्रेडिंग के दौरान, ठंडे क्षेत्रों के कोड का साइज़ कम करने का विकल्प भी चुना जा सकता है परफ़ॉर्मेंस.

परफ़ॉर्मेंस को ट्रैक करने के लिए, अच्छे वर्कलोड की पहचान करना भी फ़ायदेमंद होता है सामान्य.

दूसरा चरण: प्रोफ़ाइलें इकट्ठा करना

प्रोफ़ाइल इकट्ठा करने के तीन चरण हैं: - इंस्ट्रुमेंटेशन के साथ नेटिव कोड बनाना, - डिवाइस पर इंस्ट्रुमेंटेड ऐप्लिकेशन चलाना और प्रोफ़ाइल जनरेट करना, और - होस्ट पर मौजूद प्रोफ़ाइलों को मर्ज/प्रोसेस करने के बाद.

इंस्ट्रुमेंटेड बिल्ड बनाएं

प्रोफ़ाइलें इकट्ठा करने के लिए, पहले चरण के वर्कलोड को इस तरह से इकट्ठा किया जाता है: इंस्ट्रुमेंट्ड बिल्ड. इंस्ट्रुमेंट वाला बिल्ड जनरेट करने के लिए, जोड़ें -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 का इस्तेमाल करें प्रोफ़ाइल फ़ाइल के फ़ॉर्मैट मेल नहीं खाते.

तीसरा चरण: ऐप्लिकेशन बनाने के लिए प्रोफ़ाइलों का इस्तेमाल करना

अपने नए कंपाइलर और लिंकर को -fprofile-use=<>.profdata पास करके ऐप्लिकेशन का इस्तेमाल करें. कॉन्टेंट बनाने कोड के बेहतर होने पर भी प्रोफ़ाइलों का इस्तेमाल किया जा सकता है — क्लैंग कंपाइलर हर सोर्स और प्रोफ़ाइल के बीच थोड़ा-बहुत अंतर है.

ध्यान दें: आम तौर पर, ज़्यादातर लाइब्रेरी के लिए प्रोफ़ाइल सभी आर्किटेक्चर में एक जैसी होती हैं. उदाहरण के लिए, लाइब्रेरी के Arm64 बिल्ड से जनरेट की गई प्रोफ़ाइल का इस्तेमाल इनके लिए किया जा सकता है सभी आर्किटेक्चर. सबसे अहम बात यह है कि अगर लाइब्रेरी में मौजूद कोड पाथ (आर्म बनाम x86 या 32-बिट बनाम 64-बिट), अलग-अलग प्रोफ़ाइलें का इस्तेमाल ऐसे हर कॉन्फ़िगरेशन के लिए किया जाना चाहिए.

यह रही पूरी जानकारी

https://github.com/DanAlbert/ndk-sample/tree/pgo/pgo किसी ऐप्लिकेशन से PGO इस्तेमाल करने के लिए एंड-टू-एंड डेमो दिखाता है. यह अतिरिक्त जानकारी जो इस दस्तावेज़ में शामिल किए गए हैं.

  • CMake बिल्ड नियम CMake वैरिएबल सेटअप करने का तरीका बताएं जो इंस्ट्रुमेंटेशन के साथ नेटिव कोड बनाता है. बिल्ड वैरिएबल सेट न होने पर, नेटिव कोड को पहले वाले वर्शन का इस्तेमाल करके ऑप्टिमाइज़ किया जाता है जनरेट की गई PGO प्रोफ़ाइल.
  • इंस्ट्रुमेंटेड बिल्ड में, pgodemo.cpp लिखता है कि प्रोफ़ाइल, वर्कलोड को एक्ज़ीक्यूट कर रही हैं.
  • रनटाइम के दौरान, प्रोफ़ाइलों के लिए एक लिखने लायक जगह की जानकारी मिलती है MainActivity.kt applicationContext.cacheDir.toString() का इस्तेमाल करके.
  • adb root की ज़रूरत के बिना, डिवाइस से प्रोफ़ाइल पाने के लिए, adb का इस्तेमाल करें रेसिपी यहां क्लिक करें.