翻譯的比較爛,自己記錄下。
啟動時間最佳化
Alexander belloni,Michael Opdenacker Free Electrons
簡單的進程資訊
簡單的最佳化分為如下方面講:
原則
如何測量
使用者地區
核心
啟動 bootloader
筆記:完成樣本鏡像,測量啟動時間,最佳化啟動指令碼,最佳化核心
原則:
1. 減少啟動時間意味著首先要測量啟動時間
2. 你需要選擇啟動和停止的參考點,即啟動時間開始到結束的點。
一些減少啟動時間的意見:
1. 最快的代碼是代碼沒有被執行
2. Boot的一大部分時間是將代碼和資料從儲存空間搬到ram。讀取少的代碼和資料就會更快。I/O操作是耗時的。
3. 檔案系統越大載入時間越長。
4. 所以沒有啟動並執行代碼會讓你的啟動時間更長
5. 當然不同的儲存空間都不一樣,一般sd卡要比nand快。
6. 使用gcc編譯的時候用-0s的參數會讓代碼更小,但是代碼將失去一些特性,這也行是一個辦法。
學習開發板的影響
學習如何?它
測量 measuring
1. 最好的儀器是示波器。
2. 測試上電啟動時間,這是非常精準的測試方式。
3. 系統啟動時寫GPIO口和儲存空間是非常簡單的。
4. 一些示波器能夠負擔得起。
5. 通常你不想用示波器,或者不想冒硬體串連的風險。
6. 通常我們通過串口反饋啟動時間資訊。必須用一些軟體串連。
7. 需要即時串口,可以通過啟動進程實現。
8. 限制:不能檢測到上電時間POWER ON。但是可以保證啟動開始第一階段時間不變。
9. 序列埠使用USB轉換的連接埠串連。
10. 使用USB轉串口會丟掉一些時間精度。
11. 所有開發板都有這個標準的usb序列埠。
來著 Tim Bird: grabserial 這個命令http://elinux.org/Grabserial
一個python指令碼加入時間戳記資訊從串口控制台輸出。
按鍵優勢:開始計數非常早bootstrap和bootloader
另外一個優勢:不用上層調試直接運行在主裝置。
缺點:精度不夠,不能測量上電時間。
多方面的時間組成
初始化指令碼 init scripts
這有多種方法測量這個時間在初始化指令碼裡面重開始到應用啟動。
1. 開啟應用的同時儘可能的滿足應用必須要的條件。
2. 簡化shell指令碼
3. 啟動應用和init一起或在它之前。
如果你需要比grabserial更詳細的描述你可以使用bootchart
你可以使用bootchartd在busybox CONFIG_BOOTCHARTD=y
啟動你的板子在啟動命令列加入 init=/sbin/bootchartd
拷貝/var/log/bootlog.tgz從你的目標板到你的主機分析
普通的timechart:
Cd bootchart-<version>
Java –jar bootchart.jar bootlog.tgz
Bootchart 網站:http://www.bootchart.org/
如果你在初始化項目中用了systemd,你可以使用systemd-analyze看網站
http://www.freedesktop.org/software/systemd/man/systemd-analyze.html
啟動儘可能快的在所有依賴服務啟動後:
1. 依賴服務在init進程,這是一個慢的sysV init指令碼。
2. Init指令碼啟動用字母命令開始用letter
3. 你可以用低數字在你的應用上。
4. 你可以替換init使用你的應用。
當我們最先啟動應用還能怎麼快。
開始所有的服務使用啟動指令碼,消除大多數使用/bin/sh
使用mdev代替udev。Mdev是busybox的一部分。它不是一個守護進程,所以你需要手動載入你的熱插拔驅動。
去除掉udev如果你指示需要驅動檔案,使用devtmpfs (CONFIG_DEVTMPFS),核心自動管理,使用資源更少。
使用fork/exec系統調用是非常好的。這是因為,使用shell執行調用,所以更慢。
相等的使用echo在busybox shell中的結果是一個系統調用
選擇 Shells->Standalone shell 在busybox配置中。這個配置讓busybox指令碼調用應用在任何時候都可以。
管道是一種返回調用,當然他也是用fork/exec調用的。你可以改進他們或盡量少用他們在指令碼中。
減少大小
1. 減少執行檔案和庫。去除elf段和需要的開發和調試。這個指令碼命令已經提供在交叉編譯工具BR2_STRIP_strip在建立檔案系統的時候。
2. Superstrip 更深入的去除不用的執行檔案。
3. 使用mklibs。Mklibs程式縮小共用庫他包含常規的必須和特別的執行檔案。實際使用像一些大的共用庫像 OpenGL和QT。他們經常工作在沒有源碼的時候,所以必須小心一些時候裁剪得太多。
使用Buildroot產生這個檔案系統
使用bootchart測量啟動時間
C庫
Glibc
執照:LGPL
C庫來自GUN項目
設計效能,標準編譯和可移植效能
建立所有在GUN/Linux主系統
當然,積極的維護
合適大小的嵌入式系統。
uClibc
執照:LGPL
輕量級的嵌入式系統C庫
高可配置性:許多特徵可以失能和使能通過menuconfig配置介面
智能工作在Linux/uClinux,工作在許多嵌入式架構
沒有stable(牛棚,馬廄) ABI,不同於ABI依賴庫配置
重點是大小和效能
更少的編譯時間
uClibc(2)
多種庫的介紹
幾種庫的對比最後uClibc with Thumb-2最小,編譯出來的檔案最小。
一個好的主意是用一個小的initramfs,剛剛足夠啟動應用的最小需求,啟動最終的檔案系統使用switch_root。
使用最小的C庫檔案。uClibc使用它,如果他還沒有用在你的檔案系統
使用靜態連結應用, BR2_PREFER_STATIC_LIB 在Buildroot中
不要壓縮你的initramfs如果你的核心已經壓縮了。
簡化使用者空間指令碼
應用
允許使用應用和應用子進程跟蹤所有系統調用
有用的方法:
1. 知道時間是在哪裡消耗了。
2. 例如:很容易知道檔案開啟open(),檔案操作read(),write(),和儲存空間申請消耗的時間,而不需要藉助源碼。
3. 找到最大的時間消耗。
4. 找到不必要的工作在應用和指令碼裡面,例如:開啟同一個檔案多次,或是試著開啟一個不存在的檔案
限制:你不能跟蹤init進程。
筆記:strace常用來跟蹤進程執行時的系統調用和所接收的訊號。 在Linux世界,進程不能直接存取硬體裝置,當進程需要訪問硬體裝置(比如讀取磁碟檔案,接收網路資料等等)時,必須由使用者態模式切換至核心態模式,通 過系統調用訪問硬體裝置。strace可以跟蹤到一個進程產生的系統調用,包括參數,傳回值,執行消耗的時間。
Strace不能再目標板上面編譯。
相對簡單容易的:下載一個準備模式的靜態二進位代碼到你的目標板,所以你需要他
http://git.free-electrons.com/users/michael-opdenacker/static-binaries/tree/strace
推薦使用命令:
strace –f –tt –o strace.log <program> <arguments>
-f 跟蹤子進程
-tt 顯示時間戳記使用微秒為精度。
兩種工作模式:遺產模式和穿孔模式
遺產模式:低精度,使用核心驅動實現
CONFIG_OPROFILE
使用者區工具:opcontrol和oprofiled
穿孔模式:使用硬體效能計數
CONFIG_PERF_EVENTS和GONFIG_HW_PERF_EVENTS
使用工具operf
使用硬體效能計數
CONFIG_PERF_EVENTS和CONFIG_HW_PERF_EVENTS
使用者區工具:perf。這個軟體是核心源碼的一部分,所以必須和核心同步。
使用方法: perf record /my/command
擷取這個結果命令: perf report
工具最佳化:
使用一個最佳化的工具在你的項目上。這個是你整個項目的基準。
使用gcc版本4.6.3 9.63s
使用gcc版本4.7.3 9.26s
這個結果非常依賴系統檔案大小和特性。這裡,我們大體的標準時核心特性和檔案系統不會佔用太多的時間。筆記:不要編譯檔案系統使用glibc/eglibc而不用uClibc這個開機檔案系統大小區別非常大。。。。。。
應用程式碼群組使用啟動:
找到啟動中啟動的功能,例如:使用 –finstrument-functions gcc選項。
建立一個習慣的串連指令碼,重新整理這些功能使用一個調用隊列。你能夠實現他們各自的功能使用他們各自的塊代碼通過 –ffunction-sections gcc選項。
特別的應用如大的MTD儲存塊讀取。他們讀取塊時,停止在讀取無用資料之前。
預串連功能:
預串連可以減少時間需求在開始一個執行塊裡面。
這個經常在android裡面使用
這個功能是配置知道的庫是必須要預串連的,在啟動應用時分配和維護需要的庫地址和符號。
小心對安全的影響
代碼在 http://people.redhat.com/jakub/prelink/
跟蹤和描述主應用使用strace
核心最佳化
想知道那個初始化需要的時間最長,通過initcall_debug配置放到核心啟動命令 kernel command line
最好的主意是在kernel設定檔裡面增加log配置CONFIG_LOG_BUF_SHIFT。你還需要CONFIG_PRINTK_TIME,CONFIG_KALLSYMS.
首先我們最重要的是減少這個時間而不去除特性。
1. 這個最主要的原理是用核心模式
2. 編譯任何啟動的時候不需要的東西為模組。
3. 兩個好處:核心變得更小載入更快,更少的初始化代碼執行
4. 去除一些沒有用到的特性:CONFIG_KALLSYMS,CONFIG_DEBUG_FS,CONFIG_BUG
5. 用一些特性設計你的嵌入式系統:CONFIG_SLOB,CONFIG_EMBEDDED
平衡下儲存空間讀取速度和cpu解壓的速度,你需要找到不同的壓縮方式之前的區別選擇最快的壓縮方式。
如果你不能編譯一個功能成一個模組,試試 deferred_initcalls .你的核心將收縮但是它不能執行相同的初始化。如果你確認你的應用已經準備好,再開始重新初始化之前的調用。網站:
http://elinux.org/Deferred_Initcalls
調整命令列
在各自的引導,核心有一個校正延時時間(為這個udelay功能)。這個意思是一個值是一小會的值,你需要測量它一次。在開機記錄裡找到lpj的值。
現在你可以直接使用這個lpj的參數了。這裡可以節約180ms。
這個直接加到u-boot裡面 cmd line就ok了如下:
console=ttyS0,115200 mtdparts=atmel_nand:256k(bootstrap)ro,512k(uboot)ro,256k(env),256k(env_redundant),256k(spare),512k(dtb),6M(kernel)ro,-(rootfs) rootfstype=ubifs ubi.mtd=7 root=ubi0:rootfs rw lpj=1314816
經過測試,有效果。
控制台輸出實際上需要一部分時間。你一般在產品中不需要它。它可以通過quiet參數來失能在核心命令列裡。你可以使用dmesg命令查看獲得這些資訊。
多重處理器提供SMP
SMP在初始化的時候是相當慢的。
UP系統啟動得更快一點
你可以試著在你的應用起來以後再熱載入其他核。
實用的庫減少核心啟動時間
重新編譯核心,選擇initramfs
使用initcall_debug去尋找消耗時間最長的地方
減少這種模組的數量
調整核心命令列參數。
核心:最後幾個毫秒
最佳化最後幾個毫秒,你需要去除不必要的功能
CONFIG_PRINTK=n和使用quiet是同樣的效果。
試試 CONFIG_CC_OPTIMIZE_FOR_SIZE=y 這將影響系統效能,你需要有一個標準,有一個對比。
試著減少初始化的RAM使用mem參數,更少的RAM被初始化將減少啟動時間。
模組的載入,卸載
塊層
網路塊
USB塊
去除使用a.out格式
電源管理
CONFIG_SYSFS_DEPRECATED
輸入:鍵盤/mice話筒/觸控螢幕
CONFIG_LEGACY_PTY_COUNT或者pty.legacy_count核心參數。
啟動時間最佳化
通常,bootloader的一些功能只有開發的時候需要
1. 多種不同的bootloaders在你的開發板。試試他們
2. 評估這些功能是否都真的需要。是否需要升級功能
3. 去掉啟動延時時間。U-boot他們配置為CONFIG_ZERO_BOOTDELAY_CHECK參數。Doc/README.autoboot允許你進入啟動shell
4. 也許你可以跳過這個啟動AT91的例子: http://free-electrons.com/blog/starting-linux-directly-from-at91bootstrap3/
現在,讓我們來限制啟動bootloader的一些功能
我們可以使用這個io口來實現返回有這個功能的boot。比如使用gpio_direction_input和gpio_get_value命令在指令碼裡當開始升級啟動解救核心的時候。
筆記:這個核心不能做實際的改變但是我們不能獲得精確的時間通過串口當我們選擇這個引導核心的方式的時候。
警告:有時候,核心依賴bootloader來初始化硬體,所以要小心當我們移除掉這些功能的時候。
你可以試著使用AT91bootstrap來啟動linux核心,這樣可以去掉第二階段啟動。但是你將失去一下主要的barebox的優勢。它是使用CPU的快取來載入和解壓核心的。
啟動核心是容易的對於AT91bootstrap3.你只需要配置它成linux或linux_dt就可以了
make at91sama5d3xeknf_linux_dt_defconfig
make
詳細資料看網站:
http://free-electrons.com/blog/at91bootstrap-linux/
減少啟動時間使用barebox啟動
最佳化barebox
硬體初始化
硬體需要時間初始化:
1. 電壓穩定,晶振穩定
2. 變穩定需要200ms
3. 對於一個軟體工程師,你不能做任何事情在這段時間
4. 你能做的只是測量時間和問硬體工程師是否有改進的可能。然而,這會延長CPU啟動時間,這個不可能縮短。
替代選擇
大部分使用在手機和PC。都不能接受裝置被閑置大部分時間或更長的時間。
也叫暫停到磁碟。
使用