يقدّم هذا المستند إرشادات للشركاء لتحسين أوقات التشغيل لبعض أنواع أجهزة Android يعد وقت التشغيل مكونًا مهمًا لأداء النظام على المستخدمين انتظار اكتمال التشغيل قبل أن يتمكنوا من استخدام الجهاز. للأجهزة مثل السيارات التي يتم فيها التشغيل على البارد بشكل متكرر أكثر أو سريعة التشغيل فالوقت أمر بالغ الأهمية (لا أحد يحب الانتظار لعشرات الثواني لمجرد إدخال وجهة التنقل).
يسمح Android 8.0 بتقليل أوقات التشغيل من خلال إتاحة العديد من التحسينات عبر مجموعة من المكونات. يلخص الجدول التالي هذه الأداء التحسينات (يتم قياسها على أجهزة Google Pixel وPixel XL).
المكوّن | التحسين |
---|---|
برنامج إقلاع |
|
نواة الجهاز |
|
توليف وحدات الإدخال والإخراج |
|
init.*.rc |
|
الرسوم المتحركة عند بدء التشغيل |
|
سياسة SELinux | تم حفظ 0.2 ثانية في بواسطة genfscon |
برنامج إقلاع تحسين الأداء
لتحسين برنامج الإقلاع من أجل تحسين أوقات التشغيل، اتّبِع الخطوات التالية:
- للتسجيل:
- إيقاف كتابة السجل إلى UART لأنها قد تستغرق وقتًا طويلاً مع الكثير من التسجيل. (وجدنا على أجهزة Google Pixel أنه يبطئ برنامج الإقلاع 1.5 ثانية).
- تسجيل حالات الخطأ فقط ومراعاة تخزين المعلومات الأخرى في الذاكرة بآلية منفصلة لاستردادها.
- لفك ضغط النواة، يجب مراعاة استخدام LZ4 للأجهزة المعاصرة بدلاً من GZIP (مثال التصحيح). ضع في اعتبارك أن يمكن أن تختلف خيارات ضغط النواة باختلاف خيارات التحميل وقد تعمل بعض الخيارات بشكل أفضل من غيرها باستخدام جهاز معين.
- تحقَّق من أوقات الانتظار غير الضرورية للدخول في الوضع الخاص أو الارتداد معهم.
- حوِّل وقت التشغيل في برنامج الإقلاع إلى نواة بتنسيق cmdline.
- التحقّق من ساعة وحدة المعالجة المركزية (CPU) والتفكير في التوازي (يتطلب ذلك توفُّر دعم متعدد النواة) لتحميل النواة وتهيئة الإدخال/الإخراج.
تحسين كفاءة الإدخال/الإخراج
تُعد تحسين كفاءة الإدخال والإخراج أمرًا بالغ الأهمية لتسريع وقت التمهيد والقراءة إلى تأجيل أي شيء غير ضروري إلى ما بعد التشغيل (على هاتف Google Pixel، تتم قراءة حوالي 1.2 غيغابايت من البيانات عند التشغيل).
ضبط نظام الملف
تبدأ نواة Linux القراءة مسبقًا عند قراءة الملف من البداية أو عندما تتم قراءة الوحدات بشكل تسلسلي، مما يجعل من الضروري ضبط أداة جدولة وحدات الإدخال والإخراج معلمات خصيصًا للتشغيل (الذي له عبء عمل مختلف أكثر من التطبيقات العادية).
تستفيد الأجهزة التي تدعم تحديثات (A/B) سلسة من أنظمة الملفات الضبط عند التشغيل لأول مرة (مثلاً 20 ثانية على 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 ...
متنوعة
- تفعيل حجم الجلب المسبق لتجزئة dm-verity باستخدام إعدادات النواة DM_VERITY_HASH_PREFETCH_MIN_size (الحجم التلقائي هو 128).
- لتحسين استقرار نظام الملفات وإلغاء التحقق المفروض على في كل عملية تشغيل، يمكنك استخدام أداة الإنشاء ext4 الجديدة من خلال ضبط TARGET_USES_MKE2FS في BoardConfig.mk.
تحليل وحدات الإدخال والإخراج
لفهم أنشطة وحدات الإدخال والإخراج أثناء التشغيل، يمكنك استخدام بيانات kernel ftrace (تُستخدم أيضًا بواسطة ):
trace_event=block,ext4 in BOARD_KERNEL_CMDLINE
لتقسيم الوصول إلى الملف لكل ملف، أجرِ التغييرات التالية على النواة (kernel) (نواة التطوير فقط، لا تستخدمها في نواة الإنتاج):
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, int flags, int mode, 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, flags, 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 هو جسر النواة حتى يتم إنشاء الإطار، تستغرق الأجهزة عادةً بضع ثوانٍ في مراحل بدء مختلفة.
تنفيذ المهام بالتوازي
على الرغم من أن إعداد Android الحالي عبارة عن عملية سلسلة واحدة إلى حد ما، يمكنك لا يزال بإمكانك أداء بعض المهام بالتوازي.
- يمكنك تنفيذ الأوامر البطيئة في خدمة النص البرمجي لأوامر واجهة الأوامر وربطها لاحقًا
في انتظار خاصية محددة. يتوافق Android 8.0 مع حالة الاستخدام هذه مع
الأمر
wait_for_property
. - تحديد العمليات البطيئة في البداية. يسجِّل النظام الأمر init
exec/wait_for_bro أو أي إجراء يستغرق وقتًا طويلاً (في Android 8.0، أي أمر
تستغرق أكثر من 50 ملي ثانية). مثلاً:
init: Command 'wait_for_coldboot_done' action=wait_for_coldboot_done returned 0 took 585.012ms
قد تشير مراجعة هذا السجل إلى فرص للتحسين.
- ابدأ الخدمات وفعِّل الأجهزة الملحقة في المسار الحرج مبكرًا. بالنسبة على سبيل المثال، تتطلب بعض وحدات SOC بدء الخدمات المتعلقة بالأمان قبل البدء SurfaceFlinger. مراجعة سجلّ النظام عندما يعرض ServiceManager رسالة "انتظر خدمة" — عادةً ما تكون هذه إشارة إلى وجوب بدء استخدام خدمة تابعة أولاً.
- أزِل أي خدمات وأوامر غير مستخدَمة في init.*.rc. العناصر التي لم يتم استخدامها في ينبغي تأجيل البداية إلى اكتمال التشغيل.
ملاحظة: تُعد خدمة الموقع جزءًا من عملية الإعداد، لذا استدعاء
يمكن أن يؤدي 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 ...
بدء zygote مبكرًا
يمكن للأجهزة ذات التشفير المستند إلى الملف أن تبدأ زيغوت في وقت مبكر عند بداية زيغوت (بشكل افتراضي، يتم تشغيل zygote في الفئة الرئيسية، والذي يأتي بعد ذلك بكثير من zygote-start). عند القيام بذلك، تأكد من السماح بتشغيل zygote في جميع وحدات المعالجة المركزية (CPU) قد يؤدي إعداد تكلفة المشاهدة الخاطئ إلى فرض تشغيل الزيجوت في وحدات معالجة مركزية (CPU) محددة).
إيقاف وضع توفير الطاقة
ضبط خيار توفير الطاقة لمكوّنات مثل UFS و/أو وحدة المعالجة المركزية أثناء تشغيل الجهاز تعطيل الحاكم.
تنبيه: يجب تفعيل وضع توفير الطاقة في لوضع الشاحن لتحسين الكفاءة.
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 بدء تشغيل الرسوم المتحركة مبكرًا قبل تحميل بيانات المستخدم قسم القرص. مع ذلك، حتى عند استخدام سلسلة أدوات ext4 الجديدة في Android 8.0، يجب أولاً لا تزال تظهر بشكل دوري لأسباب تتعلق بالسلامة، مما يؤدي إلى تأخير في وبدء خدمة التمهيد.
لبدء التشغيل مبكرًا، قسِّم حامل fstab إلى مرحلتين:
- في المرحلة المبكرة، يجب تثبيت الأقسام فقط (مثل
system/
وvendor/
) التي لا تتطلب تنفيذًا المستخدم، ثم بدء خدمات تشغيل الرسوم المتحركة وتبعياتها (مثل servicemanager وSurfaceflinger). - وفي المرحلة الثانية، عليك تحميل أقسام (مثل
data/
) التي لا تتطلب إجراء عمليات تحقق.
سيتم بدء تشغيل الرسوم المتحركة بشكل أسرع بكثير (وفي وقت ثابت) بغض النظر عن أمر fsck.
إنهاء التنظيف
بعد تلقّي إشارة الخروج، يبدأ التمهيد الجزء الأخير من العمل، والتي يمكن أن تؤدي إلى إبطاء وقت التشغيل. لا يحتاج النظام الذي يبدأ تشغيله بسرعة إلى قضاء وقت طويل والرسوم المتحركة التي قد تخفي أي تحسينات يتم إجراؤها بشكل فعال. ننصحك بما يلي: مما يجعل كل من التكرار الحلقي والنهاية النهائية قصيرة.
تحسين SELinux
استخدِم النصائح التالية لتحسين SELinux وزيادة أوقات التشغيل.
- استخدام تعبيرات عادية واضحة تعبير عادي غير صحيح
يمكن أن يؤدي إلى الكثير من النفقات العامة عند مطابقة سياسة SELinux
sys/devices
فيfile_contexts
. على سبيل المثال، التعبير العادي تفرض ميزة "/sys/devices/.*abc.*(/.*)?
" فحصًا لكل العناصر عن طريق الخطأ./sys/devices
أدلة فرعية تحتوي على "abc"، ما يؤدي إلى تفعيل المطابقات لكلّ من/sys/devices/abc
و/sys/devices/xyz/abc
سيؤدي تحسين هذا التعبير العادي إلى/sys/devices/[^/]*abc[^/]*(/.*)?
إلى: تفعيل مطابقة لـ/sys/devices/abc
فقط. - نقل التصنيفات إلى genfscon تعمل ميزة SELinux الحالية هذه على تمرير بادئات مطابقة الملفات إلى النواة في نظام SELinux الثنائي، حيث تطبقه الكيرنل (النواة) على نظام kernel لأنظمة الملفات. ويساعد ذلك أيضًا في إصلاح الملفات التي تم إنشاؤها بالنواة ذات التسمية الخاطئة، مما يمنع حالات السباق التي يمكن أن تحدث بين عمليات مساحة المستخدم التي تحاول الوصول هذه الملفات قبل حدوث إعادة تصنيفها.
الأدوات والأساليب
استخدِم الأدوات التالية لمساعدتك في جمع البيانات لأهداف التحسين.
رسم بياني أوّلي
يوفر مخطط Bootchart تفاصيل حمولة وحدة المعالجة المركزية (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-python3
cd ~/Documents
git clone https://github.com/xrmx/bootchart.git
cd bootchart/pybootchartgui
mv main.py.in main.py
- تَعْدِيلْ "
$ANDROID_BUILD_TOP/system/core/init/grab-bootchart.sh
" للإشارة إلى النسخة المحلية منpybootchartgui
(الموجود في~/Documents/bootchart/pybootchartgui.py
)
سيستريس
يسمح Systrace بجمع بيانات آثار الأنشطة في النواة (kernel) وAndroid أثناء بدء التشغيل. يمكن أن يساعد مؤثرات عرض النظام في تحليل مشكلة محددة أثناء التشغيل. (ومع ذلك، للتحقق من متوسط العدد أو الرقم المتراكم أثناء للتشغيل بالكامل، يصبح من الأسهل النظر إلى آثار النواة بشكل مباشر).
لتفعيل تتبُّع النظام أثناء عملية التشغيل:
- في
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_trace
adb pull /data/local/tmp/boot_trace
$ANDROID_BUILD_TOP/external/chromium-trace/systrace.py --from-file=boot_trace
يؤدي ذلك إلى تفعيل التتبُّع (وهو غير مفعَّل تلقائيًا).
للحصول على تحليل تفصيلي للإدخال/الإخراج، يُرجى أيضًا إضافة block وext4 وf2fs.