এই নথিটি নির্দিষ্ট Android ডিভাইসের বুট সময় উন্নত করার জন্য অংশীদার নির্দেশিকা প্রদান করে। বুট টাইম হল সিস্টেম পারফরম্যান্সের একটি গুরুত্বপূর্ণ উপাদান কারণ ব্যবহারকারীদের ডিভাইসটি ব্যবহার করার আগে বুট সম্পূর্ণ হওয়ার জন্য অপেক্ষা করতে হবে। গাড়ির মতো ডিভাইসগুলির জন্য যেখানে কোল্ড বুট-আপ বেশি ঘন ঘন হয়, দ্রুত বুট করার সময় গুরুত্বপূর্ণ (কেউ একটি নেভিগেশন গন্তব্য ইনপুট করার জন্য কয়েক ডজন সেকেন্ড অপেক্ষা করতে পছন্দ করে না)।
অ্যান্ড্রয়েড 8.0 উপাদানগুলির একটি পরিসীমা জুড়ে বেশ কয়েকটি উন্নতি সমর্থন করে বুট সময় হ্রাস করার অনুমতি দেয়। নিম্নলিখিত সারণীতে এই পারফরম্যান্স উন্নতির সংক্ষিপ্ত বিবরণ দেওয়া হয়েছে (যেমন Google Pixel এবং Pixel XL ডিভাইসে পরিমাপ করা হয়)।
| কম্পোনেন্ট | উন্নতি |
|---|---|
| বুটলোডার |
|
| ডিভাইস কার্নেল |
|
| I/O টিউনিং |
|
| init.*.rc |
|
| বুট অ্যানিমেশন |
|
| SELinux নীতি | genfscon দ্বারা 0.2s সংরক্ষণ করা হয়েছে৷ |
বুটলোডার অপ্টিমাইজ করুন
উন্নত বুট সময়ের জন্য বুটলোডার অপ্টিমাইজ করতে:
- লগিং করার জন্য:
- UART-তে লগ লেখা অক্ষম করুন কারণ প্রচুর লগিংয়ে এটি দীর্ঘ সময় নিতে পারে। (গুগল পিক্সেল ডিভাইসে, আমরা দেখেছি এটি বুটলোডার 1.5s কে ধীর করে দেয়)।
- শুধুমাত্র ত্রুটির পরিস্থিতিতে লগ করুন এবং পুনরুদ্ধার করার জন্য একটি পৃথক প্রক্রিয়া সহ মেমরিতে অন্যান্য তথ্য সংরক্ষণ করার কথা বিবেচনা করুন।
- কার্নেল ডিকম্প্রেশনের জন্য, GZIP এর পরিবর্তে সমসাময়িক হার্ডওয়্যারের জন্য LZ4 ব্যবহার করার কথা বিবেচনা করুন (উদাহরণ প্যাচ )। মনে রাখবেন যে বিভিন্ন কার্নেল কম্প্রেশন বিকল্পের বিভিন্ন লোডিং এবং ডিকম্প্রেশন সময় থাকতে পারে এবং কিছু বিকল্প আপনার নির্দিষ্ট হার্ডওয়্যারের জন্য অন্যদের চেয়ে ভাল কাজ করতে পারে।
- ডিবাউন্সিং/বিশেষ মোড এন্ট্রির জন্য অপ্রয়োজনীয় অপেক্ষার সময়গুলি পরীক্ষা করুন এবং সেগুলি কমিয়ে দিন।
- cmdline হিসাবে কার্নেলে বুটলোডারে কাটানো বুট সময় পাস করুন।
- CPU ঘড়ি পরীক্ষা করুন এবং কার্নেল লোডিং এবং I/O শুরু করার জন্য সমান্তরালকরণ (মাল্টি-কোর সমর্থন প্রয়োজন) বিবেচনা করুন।
I/O দক্ষতা অপ্টিমাইজ করুন
বুট করার সময়কে দ্রুততর করার জন্য I/O কার্যকারিতা উন্নত করা গুরুত্বপূর্ণ, এবং বুট না হওয়া পর্যন্ত কিছু পড়া স্থগিত করা উচিত (একটি Google Pixel-এ, বুট করার সময় প্রায় 1.2GB ডেটা পড়া হয়)।
ফাইল সিস্টেম টিউন করুন
লিনাক্স কার্নেল রিড এহেড কিক করে যখন একটি ফাইল শুরু থেকে পড়া হয় বা যখন ব্লকগুলি ক্রমানুসারে পড়া হয়, এটি বিশেষভাবে বুট করার জন্য I/O শিডিউলার পরামিতিগুলিকে টিউন করতে প্রয়োজনীয় করে তোলে (যার স্বাভাবিক অ্যাপের চেয়ে আলাদা কাজের চাপ রয়েছে)।
যে ডিভাইসগুলি নিরবিচ্ছিন্ন (A/B) আপডেট সমর্থন করে তা প্রথমবার বুট করার সময় ফাইল সিস্টেম টিউনিং থেকে ব্যাপকভাবে উপকৃত হয় (যেমন Google Pixel-এ 20s)। একটি উদাহরণ, আমরা গুগল পিক্সেলের জন্য নিম্নলিখিত পরামিতিগুলি টিউন করেছি:
on late-fs
# boot time fs tune
# boot time fs tune
write /sys/block/sda/queue/iostats 0
write /sys/block/sda/queue/scheduler cfq
write /sys/block/sda/queue/iosched/slice_idle 0
write /sys/block/sda/queue/read_ahead_kb 2048
write /sys/block/sda/queue/nr_requests 256
write /sys/block/dm-0/queue/read_ahead_kb 2048
write /sys/block/dm-1/queue/read_ahead_kb 2048
on property:sys.boot_completed=1
# end boot time fs tune
write /sys/block/sda/queue/read_ahead_kb 512
...বিবিধ
- কার্নেল কনফিগারেশন DM_VERITY_HASH_PREFETCH_MIN_SIZE (ডিফল্ট আকার হল 128) ব্যবহার করে dm-verity হ্যাশ প্রিফেচ সাইজ চালু করুন।
- ভাল ফাইল সিস্টেমের স্থিতিশীলতার জন্য এবং একটি ড্রপ করা বাধ্যতামূলক চেক যা প্রতিটি বুটে ঘটে, BoardConfig.mk এ TARGET_USES_MKE2FS সেট করে নতুন ext4 প্রজন্মের টুল ব্যবহার করুন।
I/O বিশ্লেষণ করুন
বুট করার সময় I/O ক্রিয়াকলাপ বোঝার জন্য, কার্নেল ftrace ডেটা ব্যবহার করুন (সিস্ট্রেস দ্বারাও ব্যবহৃত):
trace_event=block,ext4 in BOARD_KERNEL_CMDLINE
প্রতিটি ফাইলের জন্য ফাইল অ্যাক্সেস ব্রেকডাউন করতে, কার্নেলে নিম্নলিখিত পরিবর্তনগুলি করুন (শুধুমাত্র উন্নয়ন কার্নেল; উৎপাদন কার্নেলে ব্যবহার করবেন না):
diff --git a/fs/open.c b/fs/open.c index 1651f35..a808093 100644 --- a/fs/open.c +++ b/fs/open.c @@ -981,6 +981,25 @@ } EXPORT_SYMBOL(file_open_root); +static void _trace_do_sys_open(struct file *filp, const struct open_how *how, long fd) +{ + char *buf; + char *fname; + + buf = kzalloc(PAGE_SIZE, GFP_KERNEL); + if (!buf) + return; + fname = d_path(&filp->f_path, buf, PAGE_SIZE); + + if (IS_ERR(fname)) + goto out; + + trace_printk("%s: open(\"%s\", %d, %d) fd = %ld, inode = %ld\n", + current->comm, fname, how->flags, how->mode, fd, filp->f_inode->i_ino); +out: + kfree(buf); +} + long do_sys_open(int dfd, const char __user *filename, int flags, umode_t mode) { struct open_flags op; @@ -1003,6 +1022,7 @@ } else { fsnotify_open(f); fd_install(fd, f); + _trace_do_sys_open(f, flags, mode, fd);
বুট কর্মক্ষমতা বিশ্লেষণে সাহায্য করতে নিম্নলিখিত স্ক্রিপ্টগুলি ব্যবহার করুন।
-
system/extras/boottime_tools/bootanalyze/bootanalyze.pyবুট প্রক্রিয়ার গুরুত্বপূর্ণ ধাপগুলির একটি ব্রেকডাউন সহ বুট সময় পরিমাপ করে। -
system/extras/boottime_tools/io_analysis/check_file_read.py boot_traceপ্রতিটি ফাইলের জন্য অ্যাক্সেসের তথ্য প্রদান করে। -
system/extras/boottime_tools/io_analysis/check_io_trace_all.py boot_traceসিস্টেম-স্তরের ব্রেকডাউন দেয়।
অপ্টিমাইজ init.*.rc
Init হল কার্নেল থেকে ফ্রেমওয়ার্ক প্রতিষ্ঠিত হওয়া পর্যন্ত সেতু, এবং ডিভাইসগুলি সাধারণত বিভিন্ন init পর্যায়ে কয়েক সেকেন্ড ব্যয় করে।
সমান্তরালভাবে কাজ চালান
যদিও বর্তমান Android init কমবেশি একটি একক থ্রেডেড প্রক্রিয়া, আপনি এখনও সমান্তরালভাবে কিছু কাজ সম্পাদন করতে পারেন।
- একটি শেল স্ক্রিপ্ট পরিষেবাতে ধীর কমান্ডগুলি চালান এবং নির্দিষ্ট সম্পত্তির জন্য অপেক্ষা করে পরে যোগদান করুন। Android 8.0 একটি নতুন
wait_for_propertyকমান্ড সহ এই ব্যবহারের ক্ষেত্রে সমর্থন করে। - init-এ ধীরগতির ক্রিয়াকলাপ সনাক্ত করুন। সিস্টেমটি লগ করে init কমান্ড exec/wait_for_prop বা দীর্ঘ সময় নেয় এমন কোনো কাজ (Android 8.0-এ, যেকোনো কমান্ড 50 ms-এর বেশি সময় নেয়)। যেমন:
init: Command 'wait_for_coldboot_done' action=wait_for_coldboot_done returned 0 took 585.012ms
এই লগ পর্যালোচনা উন্নতির জন্য সুযোগ নির্দেশ করতে পারে.
- পরিষেবা শুরু করুন এবং পেরিফেরাল ডিভাইসগুলিকে জটিল পথে সক্রিয় করুন। উদাহরণস্বরূপ, কিছু SOC-এর জন্য SurfaceFlinger শুরু করার আগে নিরাপত্তা-সম্পর্কিত পরিষেবাগুলি শুরু করতে হবে। যখন ServiceManager "পরিষেবার জন্য অপেক্ষা করুন" ফেরত দেয় তখন সিস্টেম লগটি পর্যালোচনা করুন — এটি সাধারণত একটি চিহ্ন যে একটি নির্ভরশীল পরিষেবা প্রথমে শুরু করতে হবে৷
- init.*.rc-এ যেকোনো অব্যবহৃত পরিষেবা এবং কমান্ড সরান। প্রাথমিক পর্যায়ে init ব্যবহার করা হয়নি এমন কিছু বুট সম্পূর্ণ করার জন্য পিছিয়ে দেওয়া উচিত।
দ্রষ্টব্য: প্রপার্টি পরিষেবা init প্রক্রিয়ার অংশ, তাই init বিল্টইন কমান্ডে ব্যস্ত থাকলে বুট করার সময় setproperty কল করলে দীর্ঘ বিলম্ব হতে পারে।
সময়সূচী টিউনিং ব্যবহার করুন
প্রারম্ভিক বুট জন্য সময়সূচী টিউনিং ব্যবহার করুন. একটি Google Pixel থেকে উদাহরণ:
on init
# boottime stune
write /dev/stune/schedtune.prefer_idle 1
write /dev/stune/schedtune.boost 100
on property:sys.boot_completed=1
# reset stune
write /dev/stune/schedtune.prefer_idle 0
write /dev/stune/schedtune.boost 0
# or just disable EAS during boot
on init
write /sys/kernel/debug/sched_features NO_ENERGY_AWARE
on property:sys.boot_completed=1
write /sys/kernel/debug/sched_features ENERGY_AWAREকিছু পরিষেবা বুট করার সময় একটি অগ্রাধিকার বুস্ট প্রয়োজন হতে পারে। উদাহরণ:
init.zygote64.rc:
service zygote /system/bin/app_process64 -Xzygote /system/bin --zygote --start-system-server
class main
priority -20
user root
...জাইগোট তাড়াতাড়ি শুরু করুন
ফাইল-ভিত্তিক এনক্রিপশন সহ ডিভাইসগুলি জাইগোট-স্টার্ট ট্রিগারে জাইগোট শুরু করতে পারে (ডিফল্টভাবে, জাইগোট ক্লাস মেইন এ চালু করা হয়, যা জাইগোট-স্টার্টের চেয়ে অনেক পরে)। এটি করার সময়, সমস্ত CPU-তে জাইগোট চালানোর অনুমতি নিশ্চিত করুন (যেহেতু ভুল cpuset সেটিং জাইগোটকে নির্দিষ্ট CPU-তে চালানোর জন্য বাধ্য করতে পারে)।
পাওয়ার সেভিং অক্ষম করুন
ডিভাইস বুট করার সময়, UFS এবং/অথবা CPU গভর্নরের মতো উপাদানগুলির জন্য পাওয়ার সেভিং সেটিং অক্ষম করা যেতে পারে।
সতর্কতা: দক্ষতার জন্য চার্জার মোডে পাওয়ার সেভিং চালু করা উচিত।
on init # Disable UFS powersaving write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 0 write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 0 write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 0 write /sys/module/lpm_levels/parameters/sleep_disabled Y on property:sys.boot_completed=1 # Enable UFS powersaving write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1 write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1 write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1 write /sys/module/lpm_levels/parameters/sleep_disabled N on charger # Enable UFS powersaving write /sys/devices/soc/${ro.boot.bootdevice}/clkscale_enable 1 write /sys/devices/soc/${ro.boot.bootdevice}/clkgate_enable 1 write /sys/devices/soc/${ro.boot.bootdevice}/hibern8_on_idle_enable 1 write /sys/class/typec/port0/port_type sink write /sys/module/lpm_levels/parameters/sleep_disabled N
ননক্রিটিকাল ইনিশিয়ালাইজেশন স্থগিত করুন
ননক্রিটিক্যাল ইনিশিয়ালাইজেশন যেমন ZRAM-কে boot_complete এ পিছিয়ে দেওয়া যেতে পারে।
on property:sys.boot_completed=1 # Enable ZRAM on boot_complete swapon_all /vendor/etc/fstab.${ro.hardware}
বুট অ্যানিমেশন অপ্টিমাইজ করুন
বুট অ্যানিমেশন অপ্টিমাইজ করতে নিম্নলিখিত টিপস ব্যবহার করুন.
প্রারম্ভিক শুরু কনফিগার করুন
অ্যান্ড্রয়েড 8.0 ইউজারডেটা পার্টিশন মাউন্ট করার আগে বুট অ্যানিমেশন শুরু করতে সক্ষম করে। যাইহোক, Android 8.0-এ নতুন ext4 টুল চেইন ব্যবহার করার সময়ও, নিরাপত্তার কারণে fsck এখনও পর্যায়ক্রমে ট্রিগার হয়, যার ফলে বুটানিমেশন পরিষেবা শুরু করতে বিলম্ব হয়।
বুটানিমেশন তাড়াতাড়ি শুরু করতে, fstab মাউন্টটিকে দুটি পর্যায়ে বিভক্ত করুন:
- প্রাথমিক পর্যায়ে, শুধুমাত্র পার্টিশন মাউন্ট করুন (যেমন
system/এবংvendor/) যাতে রান চেকের প্রয়োজন হয় না, তারপর বুট অ্যানিমেশন পরিষেবা এবং এর নির্ভরতা (যেমন servicemanager এবং surflinger) শুরু করুন। - দ্বিতীয় পর্যায়ে, মাউন্ট পার্টিশন (যেমন
data/) যাতে রান চেকের প্রয়োজন হয়।
Fsck নির্বিশেষে বুট অ্যানিমেশন অনেক দ্রুত (এবং ধ্রুবক সময়ে) শুরু হবে।
পরিষ্কার শেষ করুন
প্রস্থান সংকেত প্রাপ্তির পরে, বুটানিমেশন শেষ অংশটি পালন করে, যার দৈর্ঘ্য বুট সময়কে ধীর করে দিতে পারে। একটি সিস্টেম যা দ্রুত বুট হয় দীর্ঘ অ্যানিমেশনের কোন প্রয়োজন নেই যা কার্যকরীভাবে কোনো উন্নতি লুকাতে পারে। আমরা পুনরাবৃত্তিকারী লুপ এবং সমাপ্তি উভয়কেই ছোট করার পরামর্শ দিই।
SELinux অপ্টিমাইজ করুন
উন্নত বুট সময়ের জন্য SELinux অপ্টিমাইজ করতে নিম্নলিখিত টিপস ব্যবহার করুন।
- পরিষ্কার রেগুলার এক্সপ্রেশন (regex) ব্যবহার করুন ।
file_contextssys/devicesজন্য SELinux নীতির সাথে মিল করার সময় খারাপভাবে গঠিত regex অনেক বেশি ওভারহেড হতে পারে। উদাহরণস্বরূপ, regex/sys/devices/.*abc.*(/.*)?ভুলবশত সমস্ত/sys/devicesসাবডিরেক্টরিগুলির একটি স্ক্যান করতে বাধ্য করে যেগুলিতে "abc" রয়েছে,/sys/devices/abcএবং/sys/devices/xyz/abcউভয়ের জন্য মিল সক্রিয় করে। এই রেজেক্সকে/sys/devices/[^/]*abc[^/]*(/.*)?শুধুমাত্র/sys/devices/abcএর জন্য একটি মিল সক্ষম করবে। - genfscon- এ লেবেল সরান । এই বিদ্যমান SELinux বৈশিষ্ট্যটি SELinux বাইনারির কার্নেলের মধ্যে ফাইল-মিলকারী উপসর্গগুলি প্রেরণ করে, যেখানে কার্নেল সেগুলিকে কার্নেল-উত্পন্ন ফাইল সিস্টেমে প্রয়োগ করে। এটি ভুল লেবেলযুক্ত কার্নেল-তৈরি করা ফাইলগুলিকে ঠিক করতে সাহায্য করে, রিলেবেলিং ঘটার আগে এই ফাইলগুলি অ্যাক্সেস করার চেষ্টা করার জন্য ব্যবহারকারীর স্থান প্রক্রিয়াগুলির মধ্যে ঘটতে পারে এমন রেস শর্তগুলি প্রতিরোধ করে।
সরঞ্জাম এবং পদ্ধতি
অপ্টিমাইজেশান টার্গেটের জন্য ডেটা সংগ্রহ করতে আপনাকে সাহায্য করার জন্য নিম্নলিখিত সরঞ্জামগুলি ব্যবহার করুন৷
বুটচার্ট
বুটচার্ট পুরো সিস্টেমের জন্য সমস্ত প্রক্রিয়ার CPU এবং I/O লোড ব্রেকডাউন প্রদান করে। এটির জন্য সিস্টেম ইমেজ পুনর্নির্মাণের প্রয়োজন নেই এবং সিস্ট্রেসে ডুব দেওয়ার আগে একটি দ্রুত স্যানিটী চেক হিসাবে ব্যবহার করা যেতে পারে।
বুটচার্ট সক্ষম করতে:
adb shell 'touch /data/bootchart/enabled'adb reboot
বুট আপ করার পরে, বুট চার্ট আনুন:
$ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh
শেষ হলে, প্রতিবার ডেটা সংগ্রহ করা প্রতিরোধ করতে /data/bootchart/enabled মুছুন।
bootchart.png বিদ্যমান নেই, নিম্নলিখিতগুলি করুন:- নিম্নলিখিত কমান্ড চালান:
sudo apt install python-is-python3cd ~/Documentsgit clone https://github.com/xrmx/bootchart.gitcd bootchart/pybootchartguimv main.py.in main.py -
pybootchartguiএর স্থানীয় অনুলিপি নির্দেশ করতে$ANDROID_BUILD_TOP/system/core/init/grab-bootchart.shআপডেট করুন (~/Documents/bootchart/pybootchartgui.pyএ অবস্থিত)
সিস্ট্রেস
বুট আপের সময় সিস্ট্রেস কার্নেল এবং অ্যান্ড্রয়েড উভয় ট্রেস সংগ্রহ করতে দেয়। বুট-আপের সময় সিস্ট্রেসের ভিজ্যুয়ালাইজেশন নির্দিষ্ট সমস্যা বিশ্লেষণে সাহায্য করতে পারে। (তবে, পুরো বুট চলাকালীন গড় সংখ্যা বা জমে থাকা সংখ্যা পরীক্ষা করতে, সরাসরি কার্নেল ট্রেসটি সন্ধান করা সহজ)।
বুট-আপের সময় সিস্ট্রেস সক্ষম করতে:
-
frameworks/native/cmds/atrace/atrace.rc, পরিবর্তন করুন:write /sys/kernel/debug/tracing/tracing_on 0 write /sys/kernel/tracing/tracing_on 0
প্রতি:
# write /sys/kernel/debug/tracing/tracing_on 0 # write /sys/kernel/tracing/tracing_on 0
-
device.mkফাইলে, নিম্নলিখিত লাইন যোগ করুন:PRODUCT_PROPERTY_OVERRIDES += debug.atrace.tags.enableflags=802922 PRODUCT_PROPERTY_OVERRIDES += persist.traced.enable=0
- ডিভাইস
BoardConfig.mkফাইলে, নিম্নলিখিত যোগ করুন:BOARD_KERNEL_CMDLINE := ... trace_buf_size=64M trace_event=sched_wakeup,sched_switch,sched_blocked_reason,sched_cpu_hotplug
- ডিভাইস-নির্দিষ্ট
init.rcফাইলে, নিম্নলিখিত যোগ করুন:on property:sys.boot_completed=1 // This stops tracing on boot complete write /d/tracing/tracing_on 0 write /d/tracing/events/ext4/enable 0 write /d/tracing/events/f2fs/enable 0 write /d/tracing/events/block/enable 0
বুট আপ করার পরে, ট্রেস আনুন:
adb root && adb shell atrace --async_stop -z -c -o /data/local/tmp/boot_traceadb pull /data/local/tmp/boot_trace$ANDROID_BUILD_TOP/external/chromium-trace/systrace.py --from-file=boot_trace
এটি ট্রেসিং সক্ষম করে (যা ডিফল্টরূপে অক্ষম থাকে)।
বিস্তারিত I/O বিশ্লেষণের জন্য, ব্লক এবং ext4 এবং f2fs যোগ করুন।