এই ডকুমেন্ট নির্দিষ্ট Android ডিভাইসের বুট টাইম উন্নত করার জন্য পার্টনারদের নির্দেশিকা প্রদান করে। বুট টাইম হল সিস্টেম পারফর্ম্যান্সের একটি গুরুত্বপূর্ণ অংশ কারণ ব্যবহারকারী ডিভাইস ব্যবহার করার আগে বুট সম্পূর্ণ হওয়ার জন্য অপেক্ষা করতে হয়। গাড়ির মতো ডিভাইসের ক্ষেত্রে যেখানে কোল্ড বুট-আপ আরও ঘনঘন হয়, সেখানে দ্রুত বুট টাইম থাকা অত্যন্ত গুরুত্বপূর্ণ (নেভিগেশন ডেস্টিনেশন ইনপুট করার জন্য ডজন ডজন সেকেন্ড অপেক্ষা করতে কেউ পছন্দ করে না)।
Android 8.0, বিভিন্ন কম্পোনেন্ট জুড়ে একাধিক উন্নতিকে সমর্থন করে বুট টাইম কমানোর অনুমতি দেয়। নিম্নলিখিত সারণীতে এই পারফর্ম্যান্সের উন্নতির সারসংক্ষেপ দেওয়া হয়েছে (Google Pixel এবং Pixel XL ডিভাইসে পরিমাপ করা হয়েছে)।
| কম্পোনেন্ট | উন্নতি |
|---|---|
| বুটলোডার |
|
| ডিভাইস কার্নেল |
|
| I/O টিউনিং |
|
| init.*.rc |
|
| চালু অ্যানিমেশন |
|
| SELinux নীতি | genfscon-এর মাধ্যমে ০.২ সেকেন্ড সেভ করা হয়েছে |
বুটলোডার অপ্টিমাইজ করা
বুট করার সময় আরও উন্নত করতে বুটলোডার অপ্টিমাইজ করতে:
- লগ করার জন্য:
- UART-এ লগ লেখা বন্ধ করুন, কারণ অনেক লগিংয়ের কারণে এটি অনেক সময় নিতে পারে। (Google Pixel ডিভাইসে, আমরা দেখেছি যে এটি বুটলোডারকে ১.৫ সেকেন্ড ধীরে করে দেয়)।
- শুধুমাত্র সমস্যার পরিস্থিতি লগ করুন এবং অন্যান্য তথ্য মেমরিতে স্টোর করার কথা বিবেচনা করুন যা আলাদা মেকানিজমের মাধ্যমে ফিরিয়ে আনা যায়।
- কার্নেল ডিকম্প্রেশনের জন্য, সমসাময়িক হার্ডওয়্যারের জন্য GZIP-এর পরিবর্তে LZ4 ব্যবহার করার কথা বিবেচনা করুন (উদাহরণ প্যাচ)। মনে রাখবেন যে বিভিন্ন কার্নেল কম্প্রেশন বিকল্পের জন্য লোডিং এবং ডিকম্প্রেশনের সময় আলাদা আলাদা হতে পারে এবং আপনার নির্দিষ্ট হার্ডওয়্যারের জন্য কিছু বিকল্প অন্যদের চেয়ে ভাল কাজ করতে পারে।
- ডিবাউন্সিং/বিশেষ মোড এন্ট্রির জন্য অপ্রয়োজনীয় অপেক্ষার সময় চেক করে দেখুন এবং সেটি কমান।
- বুটলোডারে অতিবাহিত বুট টাইম কার্নেলে cmdline হিসেবে পাস করুন।
- CPU ক্লক চেক করুন এবং কার্নেল লোডিং ও I/O শুরু করার জন্য প্যারালাইজেশন (মাল্টি-কোর সাপোর্ট প্রয়োজন) বিবেচনা করুন।
I/O দক্ষতা অপ্টিমাইজ করা
বুট টাইম দ্রুততর করার জন্য I/O দক্ষতা উন্নত করা খুবই গুরুত্বপূর্ণ এবং বুট না হওয়া পর্যন্ত অপ্রয়োজনীয় কিছু পড়া উচিত নয় (Google Pixel-এ, বুট করার সময় প্রায় ১.২ জিবি ডেটা পড়া হয়)।
ফাইলসিস্টেম টিউন করুন
ফাইল শুরু থেকে পড়া হলে বা ব্লকগুলি ক্রমানুসারে পড়া হলে Linux কার্নেল রিড অ্যাহেড কিক-ইন করে, যার ফলে বুট করার জন্য বিশেষভাবে I/O শিডিউলার প্যারামিটার টিউন করা প্রয়োজন (যার স্বাভাবিক অ্যাপের চেয়ে আলাদা ওয়ার্কলোড বৈশিষ্ট্য রয়েছে)।
যেসব ডিভাইস নিরবচ্ছিন্ন (A/B) আপডেট সমর্থন করে, সেগুলি প্রথমবার বুট করার সময় ফাইলসিস্টেম টিউনিং (যেমন, Google Pixel-এ ২০ সেকেন্ড) থেকে অনেক সুবিধা পায়। উদাহরণ হিসেবে, আমরা Google Pixel-এর জন্য নিম্নলিখিত প্যারামিটার টিউন করেছি:
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
...বিবিধ
- kernel config DM_VERITY_HASH_PREFETCH_MIN_SIZE ব্যবহার করে dm-verity হ্যাশ প্রিফেচ সাইজ চালু করুন (ডিফল্ট সাইজ হল ১২৮)।
- আরও ভালো ফাইল সিস্টেম স্টেবিলিটি এবং প্রতিটি বুটে হওয়া ড্রপ করা ফোর্সড চেকের জন্য, BoardConfig.mk-তে TARGET_USES_MKE2FS সেট করে নতুন ext4 জেনারেশন টুল ব্যবহার করুন।
I/O বিশ্লেষণ করুন
বুট করার সময় I/O অ্যাক্টিভিটি বুঝতে, কার্নেল ftrace ডেটা ব্যবহার করুন (এছাড়াও systrace ব্যবহার করে):
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-এ, কোনও কমান্ড
যা ৫০ মিলিসেকেন্ডের বেশি সময় নিচ্ছে) লগ করে। যেমন:
init: Command 'wait_for_coldboot_done' action=wait_for_coldboot_done returned 0 took 585.012ms
এই লগ পর্যালোচনা করলে, উন্নতির সুযোগ সম্পর্কে ধারণা পাওয়া যেতে পারে।
- পরিষেবা চালু করুন এবং ক্রিটিক্যাল পাথে পেরিফেরাল ডিভাইস আগে চালু করুন। যেমন, কিছু SOC-এর ক্ষেত্রে SurfaceFlinger শুরু করার আগে নিরাপত্তা-সম্পর্কিত পরিষেবা শুরু করতে হয়। ServiceManager "wait for service" রিটার্ন করলে সিস্টেম লগ পর্যালোচনা করুন — এটি সাধারণত একটি চিহ্ন যে কোনও নির্ভরতাযুক্ত পরিষেবা প্রথমে চালু করতে হবে ।
- init.*.rc-তে ব্যবহার করা হয় না এমন পরিষেবা ও কমান্ড সরিয়ে দিন। আর্লি স্টেজ ইনিটে ব্যবহার করা হয়নি এমন যেকোনও কিছু বুট সম্পূর্ণ হওয়া পর্যন্ত পিছিয়ে দেওয়া উচিত।
মনে রাখবেন: প্রপার্টি পরিষেবা হল init প্রসেসের অংশ, তাই বুট করার সময়
setproperty কল করলে, init যদি বিল্ট-ইন কমান্ডে ব্যস্ত থাকে, তাহলে
অনেক দেরি হতে পারে।
শিডিউলার টিউনিং ব্যবহার করুন
দ্রুত বুট করার জন্য শিডিউলার টিউনিং ব্যবহার করুন। 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
...জাইগোটের ব্যবহার তাড়াতাড়ি শুরু করা
ফাইল-ভিত্তিক এনক্রিপশন সহ ডিভাইসগুলি zygote-start ট্রিগারে (ডিফল্ট হিসেবে, zygote ক্লাস মেইন-এ লঞ্চ করা হয়, যা zygote-start-এর অনেক পরে) আগে zygote শুরু করতে পারে। এটি করার সময়, সব CPU-তে zygote চালানোর অনুমতি দিতে ভুলবেন না (কারণ ভুল cpuset সেটিংয়ের কারণে zygote নির্দিষ্ট 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}
বুট অ্যানিমেশন অপ্টিমাইজ করুন
বুট অ্যানিমেশন অপ্টিমাইজ করতে নিম্নলিখিত পরামর্শ ব্যবহার করুন।
'আর্লি স্টার্ট' কনফিগার করা
Android 8.0, userdata পার্টিশন মাউন্ট করার আগে বুট অ্যানিমেশন আগেভাগে শুরু করার সুবিধা দেয়। তবে, Android 8.0-তে নতুন ext4 টুল চেন ব্যবহার করার সময়ও, fsck এখনও নিরাপত্তার কারণে মাঝে মাঝে ট্রিগার করা হয়, যার ফলে বুটঅ্যানিমেশন পরিষেবা শুরু হতে দেরি হয়।
বুটঅ্যানিমেশন যাতে তাড়াতাড়ি শুরু হয়, তার জন্য fstab মাউন্টকে দুটি ফেজে ভাগ করুন:
- প্রাথমিক পর্যায়ে, শুধুমাত্র সেইসব পার্টিশন (যেমন
system/ওvendor/) মাউন্ট করুন যেগুলির রান চেক করার প্রয়োজন নেই, তারপর বুট অ্যানিমেশন পরিষেবা ও এর ডিপেন্ডেন্সি (যেমন servicemanager ও surfaceflinger) চালু করুন। - দ্বিতীয় পর্যায়ে, রান চেক প্রয়োজন এমন পার্টিশন (যেমন
data/) মাউন্ট করুন।
fsck নির্বিশেষে বুট অ্যানিমেশন অনেক দ্রুত (এবং একই সময়ে) শুরু হবে।
পরিষ্কার করা হয়ে গেছে
বেরিয়ে যাওয়ার সিগন্যাল পাওয়ার পরে, বুটঅ্যানিমেশন শেষ অংশটি চালায়, যার দৈর্ঘ্য বুট টাইমকে ধীর করে দিতে পারে। দ্রুত বুট হওয়া সিস্টেমে দীর্ঘ অ্যানিমেশনের প্রয়োজন হয় না, যা কার্যকরভাবে করা যেকোনও উন্নতিকে আড়াল করতে পারে। আমরা সাজেস্ট করি যে রিপিট করা লুপ ও সমাপ্তি, দুটিই যেন ছোট হয়।
SELinux অপ্টিমাইজ করা
বুট টাইম উন্নত করার জন্য SELinux অপ্টিমাইজ করতে নিম্নলিখিত পরামর্শ ব্যবহার করুন।
- পরিষ্কার রেগুলার এক্সপ্রেশন (regex) ব্যবহার করুন। খারাপভাবে তৈরি করা রেজেক্স
sys/devices-এর জন্যfile_contexts-এ SELinux নীতি ম্যাচ করানোর সময় অনেক ওভারহেড তৈরি করতে পারে। যেমন, রেজেক্স/sys/devices/.*abc.*(/.*)?ভুলবশত "abc" আছে এমন সব/sys/devicesসাবডিরেক্টরি স্ক্যান করতে বাধ্য করে, এর ফলে/sys/devices/abcও/sys/devices/xyz/abcদুটিই ম্যাচ করে। এই রেজেক্সকে/sys/devices/[^/]*abc[^/]*(/.*)?হিসেবে উন্নত করলে, শুধুমাত্র/sys/devices/abc-এর জন্য ম্যাচ করার সুবিধা চালু হবে। - লেবেল genfscon-এ সরান। এই আগে থেকে থাকা SELinux ফিচারটি SELinux বাইনারিতে কার্নেলে ফাইল-ম্যাচিং প্রিফিক্স পাস করে, যেখানে কার্নেল সেগুলিকে কার্নেল-জেনারেটেড ফাইল সিস্টেমে প্রয়োগ করে। এছাড়াও, এটি ভুল লেবেল করা কার্নেল-তৈরি করা ফাইল ঠিক করতে সাহায্য করে, রিলেবেলিং হওয়ার আগে এই ফাইলগুলি অ্যাক্সেস করার চেষ্টা করা ব্যবহারকারী স্পেস প্রসেসগুলির মধ্যে ঘটতে পারে এমন রেস কন্ডিশন প্রতিরোধ করে।
টুল ও পদ্ধতি
অপ্টিমাইজেশন টার্গেটের জন্য ডেটা সংগ্রহ করতে সাহায্য পেতে নিম্নলিখিত টুল ব্যবহার করুন।
Bootchart
Bootchart পুরো সিস্টেমের সব প্রসেসের জন্য CPU এবং I/O লোড ব্রেকডাউন প্রদান করে। এর জন্য সিস্টেম ইমেজ আবার তৈরি করার প্রয়োজন হয় না এবং systrace-এ যাওয়ার আগে এটি দ্রুত স্যানিটি চেক হিসেবে ব্যবহার করা যেতে পারে।
বুটচার্ট চালু করতে:
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 -
$ANDROID_BUILD_TOP/system/core/init/grab-bootchart.shআপডেট করেpybootchartgui-এর লোকাল কপি (~/Documents/bootchart/pybootchartgui.py-এ অবস্থিত)
Systrace
বুট-আপ করার সময় Systrace, কার্নেল ও Android ট্রেস, দুটিই সংগ্রহ করতে দেয়। বুট-আপের সময় নির্দিষ্ট সমস্যা বিশ্লেষণ করতে systrace-এর ভিজ্যুয়ালাইজেশন সাহায্য করতে পারে। (তবে, সম্পূর্ণ বুট প্রসেস চলাকালীন গড় সংখ্যা বা সঞ্চিত সংখ্যা চেক করতে, সরাসরি কার্নেল ট্রেস চেক করা সহজ)।
বুট-আপের সময় systrace চালু করতে:
-
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 যোগ করুন।