16 केबी पेज आकार

पेज साइज़, वह डेटा होता है जिसे ओएस मेमोरी में मैनेज करता है. फ़िलहाल, ज़्यादातर सीपीयू पर 4 केबी का पेज साइज़ काम करता है. इसलिए, Android OS और ऐप्लिकेशन को 4 केबी के पेज साइज़ के साथ काम करने के लिए बनाया और ऑप्टिमाइज़ किया गया है. ARM सीपीयू, 16 केबी के बड़े पेज साइज़ के साथ काम करते हैं. साथ ही, Android 15 से AOSP में, 16 केबी के पेज साइज़ के साथ Android बनाने की सुविधा भी उपलब्ध है. इस विकल्प में ज़्यादा मेमोरी का इस्तेमाल होता है, लेकिन इससे सिस्टम की परफ़ॉर्मेंस बेहतर होती है. Android 15 में, यह विकल्प डिफ़ॉल्ट रूप से चालू नहीं होता. हालांकि, यह डेवलपर मोड या डेवलपर के लिए उपलब्ध विकल्प के तौर पर उपलब्ध होता है. इससे ओईएम और ऐप्लिकेशन डेवलपर, आने वाले समय में हर जगह 16 केबी मोड पर स्विच करने की तैयारी कर सकते हैं.

Android 15 और उसके बाद के वर्शन में, 16 केबी ELF अलाइनमेंट के साथ Android बनाने की सुविधा है. यह android14-6.1 से शुरू होने वाले 4 केबी और 16 केबी वाले कर्नेल के साथ काम करता है. 16 केबी के कर्नेल के साथ इस्तेमाल करने पर, यह कॉन्फ़िगरेशन ज़्यादा मेमोरी का इस्तेमाल करता है, लेकिन सिस्टम की परफ़ॉर्मेंस को बेहतर बनाता है.

Android यूज़रस्पेस को 16 केबी पर सेट करना

16 केबी वाले पेज, सिर्फ़ 16 केबी वाले कर्नेल वाले arm64 टारगेट पर काम करते हैं. हालांकि, Cuttlefish के लिए, x86_64 पर 16 केबी यूज़रस्पेस को सिम्युलेट करने का विकल्प भी है.

arm64 टारगेट के लिए, अगर अपने कर्नेल को बनाने के लिए Kleaf का इस्तेमाल किया जाता है, तो --page_size=16k कर्नेल को 16 केबी मोड में बनाता है. अगर सीधे Linux kernel कॉन्फ़िगरेशन का इस्तेमाल किया जा रहा है, तो CONFIG_ARM64_4K_PAGES के बजाय CONFIG_ARM64_16K_PAGES सेट करके, 16 केबी वाले पेज चुने जा सकते हैं.

Android उपयोगकर्ता स्पेस में 16 केबी पेज साइज़ की सुविधा चालू करने के लिए, अपने प्रॉडक्ट पर ये बिल्ड विकल्प सेट करें:

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true, PAGE_SIZE के 'तय करें' एलिमेंट को हटा देता है. साथ ही, यह कॉम्पोनेंट को रनटाइम के दौरान पेज का साइज़ तय करने की सुविधा देता है.
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384 इससे यह पक्का होता है कि प्लैटफ़ॉर्म की ELF फ़ाइलें, 16 केबी अलाइनमेंट के साथ बनाई गई हैं. ज़रूरत से ज़्यादा साइज़ इसलिए रखा जाता है, ताकि आने वाले समय में यह ऐप्लिकेशन काम करता रहे. 16 केबी ELF अलाइनमेंट की मदद से, कर्नेल 4 केबी/16 केबी पेज साइज़ के साथ काम कर सकता है.

बिल्ड फ़्लैग की पुष्टि करना

lunch टारगेट चुनने के बाद, पुष्टि करें कि एनवायरमेंट में बिल्ड फ़्लैग सही तरीके से सेट अप किए गए हैं:

$ source build/envsetup.sh
$ lunch target

$ get_build_var TARGET_MAX_PAGE_SIZE_SUPPORTED
16384
$ get_build_var TARGET_NO_BIONIC_PAGE_SIZE_MACRO
true

अगर पिछले दो निर्देशों से 16384 और true दिखते हैं, तो इसका मतलब है कि आपके बिल्ड फ़्लैग, 16 केबी के कर्नेल के साथ काम करने के लिए सही तरीके से सेट अप किए गए हैं. हालांकि, अगर कोई बिल्ड पास हो जाता है, तो भी 16 केबी वाले एनवायरमेंट में अंतर की वजह से, रनटाइम की समस्याएं हो सकती हैं.

16 केबी पेज साइज़ सिस्टम प्रोग्रामिंग

Android वाले किसी भी डिवाइस पर मौजूद ज़्यादातर कोड, सीधे तौर पर पेज साइज़ से नहीं जुड़े होते. हालांकि, पेजों से जुड़े कोड के लिए, कोर में मेमोरी के ऐलोकेशन का व्यवहार बदल जाता है. इसलिए, आपको कोड लिखते समय इस बात का ध्यान रखना होगा कि वह न सिर्फ़ काम का हो, बल्कि बेहतर परफ़ॉर्म करे और कम से कम संसाधनों का इस्तेमाल करे.

अगर 4 केबी सिस्टम पर 1 केबी, 2 केबी या ज़्यादा से ज़्यादा 4 केबी वाले क्षेत्र में mmap को कॉल किया जाता है, तो सिस्टम इसे लागू करने के लिए 4 केबी का इस्तेमाल करता है. दूसरे शब्दों में, जब कर्नेल से मेमोरी का अनुरोध किया जाता है, तो कर्नेल को हमेशा अनुरोध की गई मेमोरी को सबसे नज़दीक के पेज साइज़ तक राउंड अप करना चाहिए. उदाहरण के लिए, अगर आपने 4 केबी के क्षेत्र के लिए 5 केबी का क्षेत्र तय किया है, तो कर्नेल 8 केबी का क्षेत्र तय करेगा.

16 केबी वाले कर्नेल पर, पेजों के ये अतिरिक्त "टेल एंड" बड़े होते हैं. उदाहरण के लिए, 1 केबी से 5 केबी तक के सभी ऐलोकेशन, 16 केबी वाले कर्नेल के साथ इस्तेमाल करने पर 16 केबी ऐलोकेट करेंगे. अगर आपने 17 केबी का अनुरोध किया है, तो यह 32 केबी का ऐलोकेशन देगा.

उदाहरण के लिए, 4 केबी वाले सिस्टम पर, दो 4 केबी के रीड-राइट ऐनोनिमस रीजन को ऐलोकेट किया जा सकता है. हालांकि, 16 केबी वाले कर्नेल पर, इसके लिए दो पेज या 32 केबी का ऐलोकेशन मिलेगा. अगर हो सके, तो 16 केबी वाले कर्नेल पर, इन क्षेत्रों को एक ही रीड या राइटर पेज में जोड़ा जा सकता है, ताकि सिर्फ़ 16 केबी का इस्तेमाल किया जा सके. 4 केबी वाले कर्नेल के मामले की तुलना में, 8 केबी बर्बाद हो जाते हैं. मेमोरी के इस्तेमाल को और कम करने के लिए, ज़्यादा पेजों को जोड़ा जा सकता है. असल में, ज़्यादा से ज़्यादा ऑप्टिमाइज़ किए गए 16 केबी वाले सिस्टम पर, 16 केबी वाले पेजों को 4 केबी वाले सिस्टम के मुकाबले कम मेमोरी की ज़रूरत होती है. इसकी वजह यह है कि एक ही मेमोरी के लिए, पेज टेबल का साइज़ चौथाई होता है.

mmap का इस्तेमाल करते समय, पक्का करें कि आपने जिस साइज़ का अनुरोध किया है उसे सबसे नज़दीकी पेज साइज़ के हिसाब से राउंड किया गया हो. इससे यह पक्का होता है कि कर्नेल के लिए तय की गई पूरी मेमोरी, यूज़रस्पेस में रनटाइम वैल्यू के तौर पर सीधे दिखती है. इसके बजाय, इसके लिए चुपचाप अनुरोध किया जाता है और चुपचाप या गलती से ऐक्सेस किया जाता है.

16 केबी ELF अलाइनमेंट वाली शेयर की गई लाइब्रेरी बनाना

Android प्रोजेक्ट का हिस्सा

  • PRODUCT_NO_BIONIC_PAGE_SIZE_MACRO := true
  • PRODUCT_MAX_PAGE_SIZE_SUPPORTED := 16384

Android प्रोजेक्ट का हिस्सा न होने वाली शेयर की गई लाइब्रेरी बनाने के लिए, आपको यह लिंकर फ़्लैग पास करना होगा:

-Wl,-z,max-page-size=16384

16 केबी ईएलएफ़ अलाइनमेंट के लिए, बाइनरी और पहले से बने प्रोग्राम की पुष्टि करना

अलाइनमेंट और रनटाइम व्यवहार की पुष्टि करने का सबसे अच्छा तरीका यह है कि 16 केबी के कंपाइल किए गए कर्नेल पर जांच करें और चलाएं. हालांकि, कुछ समस्याओं का पता पहले लगाने के लिए:

  • Android 16 (AOSP एक्सपेरिमेंटल) से, बिल्ड के समय PRODUCT_CHECK_PREBUILT_MAX_PAGE_SIZE := true को सेट किया जा सकता है. Android.bp में ignore_max_page_size: true और Android.mk में LOCAL_IGNORE_MAX_PAGE_SIZE := true का इस्तेमाल करके, कुछ समय के लिए इन निर्देशों को अनदेखा करें. ये सेटिंग, पहले से बने सभी वर्शन की पुष्टि करती हैं. साथ ही, आपको यह पता लगाने में मदद करती हैं कि कोई वर्शन अपडेट होने के बावजूद, 16 केबी के हिसाब से अलाइन नहीं है.

  • atest elf_alignment_test को चलाया जा सकता है, जो डिवाइस पर मौजूद ELF फ़ाइलों के अलाइनमेंट की पुष्टि करता है. यह पुष्टि, Android 15 और उसके बाद के वर्शन वाले डिवाइसों पर की जाती है.