प्रोफ़ाइल-निर्देशित अनुकूलन का उपयोग करें

एंड्रॉइड 13 और उससे नीचे के लिए एंड्रॉइड बिल्ड सिस्टम देशी एंड्रॉइड मॉड्यूल पर क्लैंग के प्रोफाइल-निर्देशित अनुकूलन (पीजीओ) का उपयोग करने का समर्थन करता है जिसमें ब्लूप्रिंट बिल्ड नियम हैं। यह पृष्ठ क्लैंग पीजीओ का वर्णन करता है कि पीजीओ के लिए उपयोग की जाने वाली प्रोफाइल को लगातार कैसे उत्पन्न और अद्यतन किया जाए, और पीजीओ को बिल्ड सिस्टम (उपयोग के मामले के साथ) के साथ कैसे एकीकृत किया जाए।

ध्यान दें: यह दस्तावेज़ एंड्रॉइड प्लेटफ़ॉर्म में पीजीओ के उपयोग का वर्णन करता है। एंड्रॉइड ऐप से पीजीओ का उपयोग करने के बारे में जानने के लिए, इस पृष्ठ पर जाएँ।

क्लैंग पीजीओ के बारे में

क्लैंग दो प्रकार की प्रोफाइल का उपयोग करके प्रोफ़ाइल-निर्देशित अनुकूलन कर सकता है:

  • इंस्ट्रुमेंटेशन-आधारित प्रोफ़ाइल एक इंस्ट्रुमेंटेड लक्ष्य प्रोग्राम से तैयार की जाती हैं। ये प्रोफ़ाइल विस्तृत हैं और उच्च रनटाइम ओवरहेड लगाती हैं।
  • सैंपलिंग-आधारित प्रोफ़ाइल आमतौर पर सैंपलिंग हार्डवेयर काउंटरों द्वारा निर्मित की जाती हैं। वे कम रनटाइम ओवरहेड लगाते हैं, और बाइनरी में किसी उपकरण या संशोधन के बिना एकत्र किया जा सकता है। वे उपकरण-आधारित प्रोफाइल की तुलना में कम विस्तृत हैं।

सभी प्रोफ़ाइल एक प्रतिनिधि कार्यभार से तैयार की जानी चाहिए जो ऐप के विशिष्ट व्यवहार का अभ्यास करती है। जबकि क्लैंग एएसटी-आधारित ( -fprofile-instr-generate ) और एलएलवीएम आईआर-आधारित ( -fprofile-generate) दोनों का समर्थन करता है, एंड्रॉइड इंस्ट्रूमेंटेशन-आधारित पीजीओ के लिए केवल एलएलवीएम आईआर-आधारित का समर्थन करता है।

प्रोफ़ाइल संग्रह के निर्माण के लिए निम्नलिखित झंडों की आवश्यकता है:

  • -आईआर-आधारित इंस्ट्रूमेंटेशन के लिए -fprofile-generate । इस विकल्प के साथ, बैकएंड उपकरण बिंदुओं की संख्या को कम करने और कम-वजन वाले किनारों पर उनके प्लेसमेंट को अनुकूलित करने के लिए भारित न्यूनतम स्पैनिंग ट्री दृष्टिकोण का उपयोग करता है (लिंक चरण के लिए भी इस विकल्प का उपयोग करें)। क्लैंग ड्राइवर स्वचालित रूप से प्रोफाइलिंग रनटाइम ( libclang_rt.profile- arch -android.a ) को लिंकर तक पहुंचाता है। इस लाइब्रेरी में प्रोग्राम से बाहर निकलने पर प्रोफाइल को डिस्क पर लिखने के लिए रूटीन शामिल हैं।
  • न्यूनतम डिबग जानकारी उत्पन्न करने के लिए -gline-tables-only

पीजीओ के लिए एक प्रोफ़ाइल का उपयोग क्रमशः इंस्ट्रूमेंटेशन-आधारित और सैंपलिंग-आधारित प्रोफाइल के लिए -fprofile-use= pathname या -fprofile-sample-use= pathname उपयोग करके किया जा सकता है।

नोट: जैसे ही कोड में परिवर्तन किए जाते हैं, यदि क्लैंग अब प्रोफ़ाइल डेटा का उपयोग नहीं कर सकता है तो यह -Wprofile-instr-out-of-date चेतावनी उत्पन्न करता है।

पीजीओ का प्रयोग करें

पीजीओ का उपयोग करने में निम्नलिखित चरण शामिल हैं:

  1. कंपाइलर और लिंकर को -fprofile-generate पास करके इंस्ट्रूमेंटेशन के साथ लाइब्रेरी/निष्पादन योग्य बनाएं।
  2. इंस्ट्रुमेंटेड बाइनरी पर एक प्रतिनिधि कार्यभार चलाकर प्रोफ़ाइल एकत्रित करें।
  3. llvm-profdata उपयोगिता का उपयोग करके प्रोफाइल को पोस्ट-प्रोसेस करें (विवरण के लिए, एलएलवीएम प्रोफाइल फाइलों को संभालना देखें)।
  4. कंपाइलर और लिंकर को -fprofile-use=<>.profdata पास करके पीजीओ लागू करने के लिए प्रोफाइल का उपयोग करें।

एंड्रॉइड में पीजीओ के लिए, प्रोफाइल को ऑफ़लाइन एकत्र किया जाना चाहिए और प्रतिलिपि प्रस्तुत करने योग्य निर्माण सुनिश्चित करने के लिए कोड के साथ चेक किया जाना चाहिए। कोड विकसित होने पर प्रोफ़ाइल का उपयोग किया जा सकता है, लेकिन इसे समय-समय पर पुनर्जीवित किया जाना चाहिए (या जब भी क्लैंग चेतावनी देता है कि प्रोफ़ाइल पुरानी हैं)।

प्रोफ़ाइल एकत्रित करें

क्लैंग लाइब्रेरी के इंस्ट्रूमेंटेड बिल्ड का उपयोग करके या बेंचमार्क चलाने पर हार्डवेयर काउंटरों का नमूना लेकर बेंचमार्क चलाकर एकत्रित प्रोफाइल का उपयोग कर सकता है। इस समय, एंड्रॉइड नमूना-आधारित प्रोफ़ाइल संग्रह का उपयोग करने का समर्थन नहीं करता है, इसलिए आपको एक इंस्ट्रुमेंटेड बिल्ड का उपयोग करके प्रोफ़ाइल एकत्र करनी होगी:

  1. एक बेंचमार्क और उस बेंचमार्क द्वारा सामूहिक रूप से उपयोग किए जाने वाले पुस्तकालयों के सेट की पहचान करें।
  2. बेंचमार्क और लाइब्रेरीज़ में pgo गुण जोड़ें (विवरण नीचे दिया गया है)।
  3. इन लाइब्रेरीज़ की एक इंस्ट्रुमेंटेड कॉपी के साथ एक एंड्रॉइड बिल्ड तैयार करें:
    make ANDROID_PGO_INSTRUMENT=benchmark

benchmark एक प्लेसहोल्डर है जो निर्माण के दौरान उपकरणित पुस्तकालयों के संग्रह की पहचान करता है। वास्तविक प्रतिनिधि इनपुट (और संभवतः एक अन्य निष्पादन योग्य जो बेंचमार्क की जा रही लाइब्रेरी के विरुद्ध लिंक करता है) पीजीओ के लिए विशिष्ट नहीं हैं और इस दस्तावेज़ के दायरे से बाहर हैं।

  1. किसी डिवाइस पर इंस्ट्रुमेंटेड बिल्ड को फ़्लैश या सिंक करें।
  2. प्रोफ़ाइल एकत्रित करने के लिए बेंचमार्क चलाएँ।
  3. प्रोफाइल को पोस्ट-प्रोसेस करने और उन्हें सोर्स ट्री में जांचने के लिए तैयार करने के लिए llvm-profdata टूल (नीचे चर्चा की गई) का उपयोग करें।

निर्माण के दौरान प्रोफ़ाइल का उपयोग करें

एंड्रॉइड ट्री में toolchain/pgo-profiles में प्रोफाइल की जांच करें। नाम लाइब्रेरी के लिए pgo संपत्ति की profile_file उप-संपत्ति में निर्दिष्ट नाम से मेल खाना चाहिए। लाइब्रेरी बनाते समय बिल्ड सिस्टम स्वचालित रूप से प्रोफ़ाइल फ़ाइल को क्लैंग में भेज देता है। PGO को अस्थायी रूप से अक्षम करने और इसके प्रदर्शन लाभ को मापने के लिए ANDROID_PGO_DISABLE_PROFILE_USE पर्यावरण चर को true पर सेट किया जा सकता है।

अतिरिक्त उत्पाद-विशिष्ट प्रोफ़ाइल निर्देशिकाओं को निर्दिष्ट करने के लिए, उन्हें PGO_ADDITIONAL_PROFILE_DIRECTORIES मेक वेरिएबल को एक BoardConfig.mk में जोड़ें। यदि अतिरिक्त पथ निर्दिष्ट हैं, तो इन पथों में प्रोफ़ाइल toolchain/pgo-profiles में मौजूद प्रोफ़ाइल को ओवरराइड कर देती है।

make के लिए dist लक्ष्य का उपयोग करके एक रिलीज़ छवि बनाते समय, बिल्ड सिस्टम लापता प्रोफ़ाइल फ़ाइलों के नाम $DIST_DIR/pgo_profile_file_missing.txt पर लिखता है। आप यह देखने के लिए इस फ़ाइल की जाँच कर सकते हैं कि कौन सी प्रोफ़ाइल फ़ाइलें गलती से गिर गईं (जो चुपचाप पीजीओ को अक्षम कर देती हैं)।

Android.bp फ़ाइलों में PGO सक्षम करें

देशी मॉड्यूल के लिए Android.bp फ़ाइलों में पीजीओ को सक्षम करने के लिए, बस pgo संपत्ति निर्दिष्ट करें। इस संपत्ति में निम्नलिखित उप-गुण हैं:

संपत्ति विवरण
instrumentation इंस्ट्रुमेंटेशन का उपयोग करके पीजीओ के लिए true पर सेट करें। डिफ़ॉल्ट false है.
sampling नमूने का उपयोग करके पीजीओ के लिए true पर सेट करें। डिफ़ॉल्ट false है.
benchmarks तारों की सूची. यदि सूची में कोई भी बेंचमार्क ANDROID_PGO_INSTRUMENT बिल्ड विकल्प में निर्दिष्ट है तो यह मॉड्यूल प्रोफाइलिंग के लिए बनाया गया है।
profile_file पीजीओ के साथ उपयोग करने के लिए प्रोफ़ाइल फ़ाइल ( toolchain/pgo-profile के सापेक्ष)। बिल्ड चेतावनी देता है कि इस फ़ाइल को $DIST_DIR/pgo_profile_file_missing.txt में जोड़कर यह फ़ाइल मौजूद नहीं है जब तक कि enable_profile_use प्रॉपर्टी false पर सेट न हो या ANDROID_PGO_NO_PROFILE_USE बिल्ड वेरिएबल true पर सेट न हो जाए।
enable_profile_use यदि निर्माण के दौरान प्रोफाइल का उपयोग नहीं किया जाना चाहिए तो false पर सेट करें। प्रोफ़ाइल संग्रह को सक्षम करने या पीजीओ को अस्थायी रूप से अक्षम करने के लिए बूटस्ट्रैप के दौरान उपयोग किया जा सकता है। डिफ़ॉल्ट true है.
cflags उपकरण निर्माण के दौरान उपयोग करने के लिए अतिरिक्त झंडों की सूची।

पीजीओ वाले मॉड्यूल का उदाहरण:

cc_library {
    name: "libexample",
    srcs: [
        "src1.cpp",
        "src2.cpp",
    ],
    static: [
        "libstatic1",
        "libstatic2",
    ],
    shared: [
        "libshared1",
    ]
    pgo: {
        instrumentation: true,
        benchmarks: [
            "benchmark1",
            "benchmark2",
        ],
        profile_file: "example.profdata",
    }
}

यदि बेंचमार्क benchmark1 और benchmark2 पुस्तकालयों libstatic1 , libstatic2 , या libshared1 के लिए प्रतिनिधि व्यवहार करते हैं, तो इन पुस्तकालयों की pgo संपत्ति में बेंचमार्क भी शामिल हो सकते हैं। Android.bp में defaults मॉड्यूल में कई मॉड्यूल के लिए समान निर्माण नियमों को दोहराने से बचने के लिए पुस्तकालयों के एक सेट के लिए एक सामान्य pgo विनिर्देश शामिल हो सकता है।

किसी आर्किटेक्चर के लिए अलग-अलग प्रोफ़ाइल फ़ाइलों का चयन करने या पीजीओ को चुनिंदा रूप से अक्षम करने के लिए, प्रत्येक आर्किटेक्चर के लिए profile_file , enable_profile_use , और cflags गुण निर्दिष्ट करें। उदाहरण ( बोल्ड में आर्किटेक्चर लक्ष्य के साथ):

cc_library {
    name: "libexample",
    srcs: [
          "src1.cpp",
          "src2.cpp",
    ],
    static: [
          "libstatic1",
          "libstatic2",
    ],
    shared: [
          "libshared1",
    ],
    pgo: {
         instrumentation: true,
         benchmarks: [
              "benchmark1",
              "benchmark2",
         ],
    }

    target: {
         android_arm: {
              pgo: {
                   profile_file: "example_arm.profdata",
              }
         },
         android_arm64: {
              pgo: {
                   profile_file: "example_arm64.profdata",
              }
         }
    }
}

इंस्ट्रूमेंटेशन-आधारित प्रोफाइलिंग के दौरान प्रोफाइलिंग रनटाइम लाइब्रेरी के संदर्भों को हल करने के लिए, बिल्ड फ़्लैग -fprofile-generate को लिंकर पर पास करें। पीजीओ के साथ संचालित स्थैतिक पुस्तकालय, सभी साझा पुस्तकालय, और कोई भी बाइनरी जो सीधे स्थैतिक पुस्तकालय पर निर्भर करती है, उसे भी पीजीओ के लिए यंत्रीकृत किया जाना चाहिए। हालाँकि, ऐसे साझा पुस्तकालयों या निष्पादनयोग्यों को पीजीओ प्रोफाइल का उपयोग करने की आवश्यकता नहीं है, और उनकी enable_profile_use संपत्ति को false पर सेट किया जा सकता है। इस प्रतिबंध के बाहर, आप पीजीओ को किसी भी स्थिर लाइब्रेरी, साझा लाइब्रेरी या निष्पादन योग्य पर लागू कर सकते हैं।

एलएलवीएम प्रोफ़ाइल फ़ाइलें संभालें

किसी इंस्ट्रूमेंटेड लाइब्रेरी या निष्पादन योग्य को निष्पादित करने से /data/local/tmp में default_ unique_id _0.profraw नामक एक प्रोफ़ाइल फ़ाइल तैयार होती है (जहाँ unique_id एक संख्यात्मक हैश है जो इस लाइब्रेरी के लिए अद्वितीय है)। यदि यह फ़ाइल पहले से मौजूद है, तो प्रोफ़ाइल लिखते समय प्रोफ़ाइलिंग रनटाइम नई प्रोफ़ाइल को पुरानी प्रोफ़ाइल के साथ मर्ज कर देता है। ध्यान दें कि /data/local/tmp ऐप डेवलपर्स के लिए पहुंच योग्य नहीं है; उन्हें इसके बजाय /storage/emulated/0/Android/data/ packagename /files जैसे कहीं उपयोग करना चाहिए। प्रोफ़ाइल फ़ाइल का स्थान बदलने के लिए, रनटाइम पर LLVM_PROFILE_FILE पर्यावरण चर सेट करें।

llvm-profdata उपयोगिता का उपयोग .profdata फ़ाइल को .profraw फ़ाइल में बदलने (और संभवतः कई .profraw फ़ाइलों को मर्ज करने) के लिए किया जाता है:

  llvm-profdata merge -output=profile.profdata <.profraw and/or .profdata files>

profile.profdata निर्माण के दौरान उपयोग के लिए स्रोत ट्री में जांचा जा सकता है।

यदि एक बेंचमार्क के दौरान एकाधिक इंस्ट्रूमेंटेड बायनेरिज़/लाइब्रेरी लोड की जाती हैं, तो प्रत्येक लाइब्रेरी एक अलग अद्वितीय आईडी के साथ एक अलग .profraw फ़ाइल उत्पन्न करती है। आमतौर पर, इन सभी फ़ाइलों को एक एकल .profdata फ़ाइल में मर्ज किया जा सकता है और PGO बिल्ड के लिए उपयोग किया जा सकता है। ऐसे मामलों में जहां एक लाइब्रेरी का उपयोग किसी अन्य बेंचमार्क द्वारा किया जाता है, उस लाइब्रेरी को दोनों बेंचमार्क से प्रोफाइल का उपयोग करके अनुकूलित किया जाना चाहिए। इस स्थिति में, llvm-profdata का show विकल्प उपयोगी है:

  llvm-profdata merge -output=default_unique_id.profdata default_unique_id_0.profraw
llvm-profdata show -all-functions default_unique_id.profdata

यूनिक_आईडी को अलग-अलग लाइब्रेरी में मैप करने के लिए, लाइब्रेरी के लिए अद्वितीय फ़ंक्शन नाम के लिए प्रत्येक यूनिक_आईडी के लिए show आउटपुट खोजें।

केस स्टडी: एआरटी के लिए पीजीओ

केस स्टडी एआरटी को एक संबंधित उदाहरण के रूप में प्रस्तुत करती है; हालाँकि, यह एआरटी या उनकी अन्योन्याश्रितताओं के लिए प्रोफाइल किए गए पुस्तकालयों के वास्तविक सेट का सटीक विवरण नहीं है।

एआरटी में dex2oat अग्रिम समय का कंपाइलर libart-compiler.so पर निर्भर करता है, जो बदले में libart.so पर निर्भर करता है। एआरटी रनटाइम मुख्य रूप से libart.so में लागू किया गया है। कंपाइलर और रनटाइम के लिए बेंचमार्क अलग-अलग होंगे:

बेंचमार्क प्रोफ़ाइलयुक्त पुस्तकालय
dex2oat dex2oat (निष्पादन योग्य), libart-compiler.so , libart.so
art_runtime libart.so
  1. निम्नलिखित pgo प्रॉपर्टी को dex2oat , libart-compiler.so में जोड़ें:
        pgo: {
            instrumentation: true,
            benchmarks: ["dex2oat",],
            profile_file: "dex2oat.profdata",
        }
  2. निम्नलिखित pgo प्रॉपर्टी को libart.so में जोड़ें:
        pgo: {
            instrumentation: true,
            benchmarks: ["art_runtime", "dex2oat",],
            profile_file: "libart.profdata",
        }
  3. इसका उपयोग करके dex2oat और art_runtime बेंचमार्क के लिए इंस्ट्रुमेंटेड बिल्ड बनाएं:
        make ANDROID_PGO_INSTRUMENT=dex2oat
        make ANDROID_PGO_INSTRUMENT=art_runtime
  4. वैकल्पिक रूप से, सभी लाइब्रेरीज़ का उपयोग करके एक एकल इंस्ट्रुमेंटेड बिल्ड बनाएं:

        make ANDROID_PGO_INSTRUMENT=dex2oat,art_runtime
        (or)
        make ANDROID_PGO_INSTRUMENT=ALL

    दूसरा कमांड प्रोफाइलिंग के लिए सभी पीजीओ-सक्षम मॉड्यूल बनाता है।

  5. प्राप्त करने के लिए dex2oat और art_runtime प्रयोग करते हुए बेंचमार्क चलाएँ:
  6. dex2oat निष्पादन योग्य और libart-compiler.so के लिए एक सामान्य profdata फ़ाइल तैयार करें:
    llvm-profdata merge -output=dex2oat.profdata \
        dex2oat_exe.profdata dex2oat_libart-compiler.profdata
  7. दो बेंचमार्क से प्रोफाइल को मर्ज करके libart.so के लिए प्रोफाइल प्राप्त करें:
    llvm-profdata merge -output=libart.profdata \
        dex2oat_libart.profdata art_runtime_libart.profdata

    दो प्रोफाइलों से libart.so के लिए मूल गणना अलग-अलग हो सकती है क्योंकि बेंचमार्क परीक्षण मामलों की संख्या और उनके चलने की अवधि में भिन्न होते हैं। इस मामले में, आप भारित मर्ज का उपयोग कर सकते हैं:

    llvm-profdata merge -output=libart.profdata \
        -weighted-input=2,dex2oat_libart.profdata \
        -weighted-input=1,art_runtime_libart.profdata

    उपरोक्त आदेश dex2oat से प्रोफ़ाइल को दोगुना भार प्रदान करता है। वास्तविक वजन डोमेन ज्ञान या प्रयोग के आधार पर निर्धारित किया जाना चाहिए।

  8. निर्माण के दौरान उपयोग के लिए toolchain/pgo-profiles में प्रोफ़ाइल फ़ाइलों dex2oat.profdata और libart.profdata जाँच करें।